寫在前面的話
從08年接觸Python到現在,斷斷續續地使用,到如今Python已經成為日常事物處理、科研實驗,甚至工程項目的主力語言,主要因為其敏捷性和快速實現的能力。雖然看了一些Python的教程,除了當初那本《Python核心編程》被反復翻看之外,其余還沒看到很能讓自己Python水平提高的書,雖然也掌握了一些比較Pythonic的方法,但總覺得離真正的深入理解和運用還很遠,就像一直屬于業余選手,算不上專業隊伍那般。直到最近在看《編寫高質量代碼——改善Python程序的91個建議》和《Python開發實戰》,開始有點眼前一亮的感覺,所以,趁此機會,在讀書學習的過程中把一些有意思的Pythonic Code做個記錄,也方便自己以后查閱。
代碼風格與規范
1. 包和模塊的命名采用小寫、單數形式,而且短小;
2. 包通常僅作為命名空間,如只包含空的__init__.py文件;
參數變量操作
1. 三元操作
1 x=02 y=13 PRint x if x>y else y4 5 #等價于6 if x>y:7 print x8 else:9 print y
2. 將常量集中到一個文件中
1 # const.py 2 class _const: 3 class ConstError(TypeError): pass 4 class ConstCaseError(ConstError): pass 5 6 def __setattr__(self, name, value): 7 if self.__dict__.has_key(name): 8 raise self.ConstError, "Can't Change const %s." % name 9 if not name.isupper():10 raise self.ConstCaseError, /11 'const name "%s" is not all uppercase' % name12 self.__dict__[name] = value13 14 import sys15 sys.modules[__name__] = _const()16 17 # 存放常量的文件 constant.py18 import const19 20 const.MY_CONSTANT = 1
3. 枚舉類型
使用第三方模塊flufl.enum,注:flufl不支持枚舉元素比較
1 from flufl.num import Enum 2 #方法一:通過繼承的方式實現 3 class Seasons(Enum): 4 Spring = "Spring" 5 Summer = 2 6 Autumn = 3 7 Winter = 4 8 #方法二:直接初始化為Enum類的實例 9 Seasons = Enum('Seasons', 'Spring Summer Autumn Winter')10 11 #使用枚舉值12 #方法一:得到枚舉項的名稱13 print [member for member in Seasons.__members__]14 #方法二:得到枚舉項的值15 print Seasons.Summer.value
4. 類型檢查
使用isinstance(object, classinfo)
5.字符串操作
a. 格式化字符串
1 #在參數比較多的情況下,這樣寫使得格式化的字符串比較清晰,尤其當參數以dict傳遞時2 print 'hello %(name)s' % {'name': 'Tom'}3 4 #使用str.format()也可以使字符串格式化變得清晰5 print '%(name)s is %(age)d years old.' % {'name': 'Tom', 'age': 12}
b. 格式化字符串使用format(),更為靈活
weather = [("Monday", "rain"), ("Tuestday", "sunny")]formatter = "Weather of '{0[0]}' is '{0[1]}'".formatfor item in map(formatter, weather): print item
6. 判斷數值=或!=時,盡量使用整型數,浮點數可能由于精度不一,導致無法獲得精確一致使判斷條件得以滿足。
7. 在不可信的計算環境中,盡量避免使用eval(),使用ast.literal_eval代替。
8. 將對象轉換成字符串表示,有repre()和str()兩種方法:
str()一般是將數值轉成字符串。 
repr()是將一個對象轉成字符串顯示,注意只是顯示用,有些對象轉成字符串沒有直接的意思。如list,dict使用str()是無效的,但使用repr可以,這是為了看它們都有哪些值,為了顯示之用。
9. 函數傳參既不是傳值也不是傳引用,準確的說法是傳對象或者說傳對象的引用。對可變對象的修改在函數外部以及內部都可見,調用者和被調用者之間共享這個對象,而對于不可變對象,由于并不能真正被修改,因此,修改往往是通過生成一個新的對象然后賦值實現。(書p75)
列表解析
語法: [expr for iter_item in iterable if cond_expr]
1. 多重迭代,例如兩個集合的笛卡爾乘積:
>>> [(a, b) for a in ['a', 1, '1', 'b'] for b in ['1', 2, '2', 'b'] if a!=b][('a', '1'), ('a', 2), ('a', '2'), ('a', 'b'), (1, '1'), (1, 2), (1, '2'), (1, 'b'), ('1', 2), ('1', '2'), ('1', 'b'), ('b', '1'), ('b', 2), ('b', '2')]
排序
sorted()作用于任意可迭代的對象,list.sort()一般作用于列表,sorted()不改變原有序列對象,返回一個新的對象,而sort()直接改變原有列表。
1. 多鍵值排序
#這里有兩個同為ann,但年齡分別為2和3的小孩>>> person = [{'name':'joe', 'age':2},{'name':'ann','age':3},{'name':'ben','age':5},{'name':'ann','age':2}]#同時考慮name和age兩個鍵值的排序>>> sorted(person, key=lambda x: (x['name'],-x['age'])) [{'age': 3, 'name': 'ann'}, {'age': 2, 'name': 'ann'}, {'age': 5, 'name': 'ben'}, {'age': 2, 'name': 'joe'}]#注意這里的鍵值順序>>> sorted(person, key=lambda x: (x['age'],x['name'])) [{'age': 2, 'name': 'ann'}, {'age': 2, 'name': 'joe'}, {'age': 3, 'name': 'ann'}, {'age': 5, 'name': 'ben'}]#另外一種排序方法>>> from Operator import itemgetter>>> sorted(person, key=itemgetter('name','age'))[{'age': 2, 'name': 'ann'}, {'age': 3, 'name': 'ann'}, {'age': 5, 'name': 'ben'}, {'age': 2, 'name': 'joe'}]
2. 字典中混合list排序
>>> mydict = {'Li':[1,'b'],... 'zhang':[3,'e'],... 'Wang':[2,'a']}>>> sorted(mydict.iteritems(), key=lambda (k,v): itemgetter(1)(v))[('Wang', [2, 'a']), ('Li', [1, 'b']), ('zhang', [3, 'e'])]>>> sorted(mydict.iteritems(), key=lambda (k,v): itemgetter(0)(v))[('Li', [1, 'b']), ('Wang', [2, 'a']), ('zhang', [3, 'e'])]3. 多維list排序
>>> results = [['ann',10,'b'],['ben',9,'a'],['aris',9,'c']]>>> sorted(results, key=itemgetter(2,1))[['ben', 9, 'a'], ['ann', 10, 'b'], ['aris', 9, 'c']]>>> sorted(results, key=itemgetter(1,2))[['ben', 9, 'a'], ['aris', 9, 'c'], ['ann', 10, 'b']]>>> sorted(results, key=itemgetter(0,1))[['ann', 10, 'b'], ['aris', 9, 'c'], ['ben', 9, 'a']]>>> sorted(results, key=itemgetter(0))[['ann', 10, 'b'], ['aris', 9, 'c'], ['ben', 9, 'a']]
新聞熱點
疑難解答