寫在前面的話編程
從08年接觸Python到如今,斷斷續續地使用,到現在Python已經成爲平常事物處理、科研實驗,甚至工程項目的主力語言,主要由於其敏捷性和快速實現的能力。雖然看了一些Python的教程,除了當初那本《Python核心編程》被反覆翻看以外,其他還沒看到很能讓本身Python水平提升的書,雖然也掌握了一些比較Pythonic的方法,但總以爲離真正的深刻理解和運用還很遠,就像一直屬於業餘選手,算不上專業隊伍那般。直到最近在看《編寫高質量代碼——改善Python程序的91個建議》和《Python開發實戰》,開始有點眼前一亮的感受,因此,趁此機會,在讀書學習的過程當中把一些有意思的Pythonic Code作個記錄,也方便本身之後查閱。函數
代碼風格與規範學習
1. 包和模塊的命名採用小寫、單數形式,並且短小;spa
2. 包一般僅做爲命名空間,如只包含空的__init__.py文件;code
參數變量操做orm
1. 三元操做 對象
1 x=0 2 y=1 3 print x if x>y else y 4 5 #等價於 6 if x>y: 7 print x 8 else: 9 print y
2. 將常量集中到一個文件中blog
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' % name 12 self.__dict__[name] = value 13 14 import sys 15 sys.modules[__name__] = _const() 16 17 # 存放常量的文件 constant.py 18 import const 19 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]}'".format for 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']]