be pythonicpython
遵照pep8算法
python3有兩種字符序列類型:bytes(原始的字節)和str(Unicode字符).安全
數據結構
應該儘量使用if/else表達式和輔助函數來使代碼清晰多線程
不要在單次切片中同時指定start, end和stride.能夠採用兩步進行範圍切割和步進切割.閉包
使用列表推導來代替map和filter併發
不要在列表推導中使用兩個以上的表達式.使用if和for語句代替.ide
若是數據量很大,用生成器表達式來改寫列表推導.生成器表達式會返回一個迭代器,而後能夠用next來生成新值.函數
若是須要同時使用list的索引和元素,最好使用enumerate替代range性能
用zip函數同時遍歷2個迭代器
利用try/except/else/finally進行異常處理
儘可能用異常來表示特殊狀況,而不是None
python支持閉包,閉包是一種定義在某個做用域的函數,這種函數引用了那個做用域裏的變量.
python的函數是一級對象,也就是能夠直接引用,能夠賦給變量,能夠當成參數傳給其餘函數.
函數中的局部變量不會影響外部做用域.若是須要獲取閉包函數內的數據,應該使用nonlocal聲明變量.若是使用nonlocal讓代碼變得複雜,應該將相關的函數封裝成輔助類.
若是函數返回列表,能夠考慮用生成器改寫,將return變爲yield.
若是須要在函數中屢次迭代一個生成器,能夠考慮把寫一個容器,把__iter__方法實現爲生成器.
令函數接受可選的位置參數*args,可以使代碼清晰.若是要把列表中的全部元素做爲位置參數傳入,就在列表前加上*.
可選參數有兩個問題,一個是過長的生成器做爲參數會致使消耗大量內存,一個是不方便修改函數.
能夠用關鍵字參數表示函數可選的行爲和默認值.參數的默認值會在模塊加載的時候求出.所以不要在參數默認值中建立[]或{}等動態的值.解決方法是把默認值設爲None,並在docstring中具體解釋.
能夠在定義函數的時候用*來分隔位置參數和關鍵字參數(只能以關鍵字指定的參數)
當數據結構比較複雜時,儘可能用輔助類來維護程序的狀態,而不要用字典和元組.
相似sort的key參數能夠接受一個函數,這稱掛鉤(hook)函數.
簡單的接口應該接受函數而不是類的實例,由於函數是一級對象.
若是要用函數保存狀態,應該定義新的類並實現__call__方法
經過@classmethod能夠構造多態的類的對象.
較複雜的繼承體系中,若是仍讓子類直接調用父類的__init__,會出現不少意想不到的行爲,所以建議用super初始化父類.
mix-iin是一種只定義了其餘類可能須要提供的一套附加方法的小型類.只在使用mix-in組件類時進行多重繼承.
Python類的屬性只有public和private.通常還會用單個下劃線開頭來習慣性命名protected.
private屬性是開頭至少有兩個下劃線,結尾至多有一個下劃線的屬性.python對於__private_name的保存機制其實是_ClassName__private_name.所以能夠經過這種方式訪問全部private屬性.
應該多用前者,少用後者.
若是要定製簡單子類,能夠直接從python的容器類型繼承.不然能夠繼承collections.abc中的抽象基類以實現自定義的容器類型.
用純屬性取代get和set方法
若是想要使用get和set,應該使用@property修飾器的getter和setter.它的缺點是不便於複用.
描述符能夠把同一套邏輯運用在類中的不一樣屬性上面.
WeakKeyDictionary能夠保證描述符類不會泄露內存
併發(concurrency)是指計算機經過迅速切換看似在同一時間作不少不一樣的事.並行(parallelism)則是指計算機確實在同一時間作不少不一樣的事.
subprocess用於與外部進程交互.
Python解釋器能平行地運行多條子進程.
GIL確保了字節碼解釋器的協調性,但也帶來了同一時刻只能進行一條線程的負面影響.所以Python的多線程適用於處理阻塞式的I/O操做,而不是平行計算.
Python多線程一樣須要使用Lock來防止數據競爭,由於解釋器可能會在線程的任意時刻暫停它們.
用queue.QUeue來協調各線程之間的工做.它解決了併發式管道存在的問題.
線程存在的問題是:代碼複雜,須要佔用大量內存(大約8mb),啓動時的開銷比較大.協程能夠避免這些問題.
協程的工做原理是:每當生成器函數執行到yield表達式時,消耗生成器的那段代碼,就經過send方法給生成器回傳一個值.
concurrent.futures會以子進程的形式平行地運行多個解釋器,從而令python可以利用多核心CPU來提高速度.這種作法適用於較爲孤立且數據利用率高的任務.
functools.wraps能夠定義函數修飾器,用於在函數執行以前以及執行完畢以後分別運行一些附加代碼.能夠實現約束語義,調試程序,註冊函數等目標.
contextlib模塊可使本身編寫的對象和函數支持with語句.
python的pickle模塊能將python對象序列化爲字節流,也能將這些字節反序列化爲python對象.可是這種序列化數據採用的是不安全的格式,若是其中有惡意信息,在反序列化時可能對程序形成損害.Json數據則是安全的.
copyreg能使pickle變得可靠.
使用datetime而不是time來處理本地時間
使用內置的算法和數據結構,例如collections.deque雙向隊列,collections.OrderedDict有序字典,collections.defaultdict帶有默認值的字典,heapq堆,bisect二分查找,itertools處理迭代器.
在重視精確度的場合,應該使用decimal
爲每一個函數,類和模塊編寫docstring.
用包來安排模塊,並提供穩固的API.
爲自編的模塊定義根異常,以便將調用者與API相隔離.
能夠用模塊級別的代碼來配置不一樣的部署環境
經過repr來輸出調試信息
用unittest來測試代碼
pdb模塊的set_trace()可讓程序在執行到某一行的時候暫停,用於調試.
利用cProfile來分析每一個模塊的性能,而後再優化.
用tarcemalloc來掌握內存的使用及泄露狀況.