python3-cookbook中每個小節以問題、解決方案和討論三個部分探討了Python3在某類問題中的最優解決方式,或者說是探討Python3本身的數據結構、函數、類等特性在某類問題上如何更好地使用。這本書對於加深Python3的理解和提升Python編程能力的都有顯著幫助,特別是對怎麼提高Py ...
python3-cookbook中每個小節以問題、解決方案和討論三個部分探討了Python3在某類問題中的最優解決方式,或者說是探討Python3本身的數據結構、函數、類等特性在某類問題上如何更好地使用。這本書對於加深Python3的理解和提升Python編程能力的都有顯著幫助,特別是對怎麼提高Python程式的性能會有很好的幫助,如果有時間的話強烈建議看一下。
本文為學習筆記,文中的內容只是根據自己的工作需要和平時使用寫了書中的部分內容,並且文中的示例代碼大多直接貼的原文代碼,當然,代碼多數都在Python3.6的環境上都驗證過了的。不同領域的編程關註點也會有所不同,有興趣的可以去看全文。
python3-cookbook:https://python3-cookbook.readthedocs.io/zh_CN/latest/index.html
7.2 只接受關鍵字參數的函數
有時候為了代碼可讀性或者其他原因,我們需要在使用函數的時候強制要求調用者使用關鍵字參數,這時候只需要在某個*參數或單個*後面定義關鍵字參數即可。
def print_ax(a, x): print(a, x) def print_x(a, *, x): print(a, x) print_ax(111, 222) # 如果這樣寫就會報錯:print_x(111, 222) print_x(111, x=222)
7.7 匿名函數捕獲變數值
lambda表達式的參數值是在運行時綁定的,而不是定義時綁定的,這跟def定義參數預設值是不同的,如果需要lambda表達式在定義時就綁定值,可以使用參數預設值的寫法。
>>> x = 10 >>> a = lambda y: x + y >>> x = 20 >>> b = lambda y: x + y >>> # 下麵兩個執行結果是一樣的 >>> a(10) 30 >>> b(10) 30 >>> x = 30 >>> a(10) 40 >>> b(10) 40 >>> # 使用參數預設值的方式 >>> a = lambda y, x=x: x + y >>> b = lambda y, x=x: x + y >>> a(10) 40 >>> b(10) 40 >>>
7.8 減少可調用對象的參數個數
當調用某個函數的時候可能你並不需要傳入全部參數值,或者只能傳入部分參數值,就可以使用functools.partial()。
用法示例:
>>> from functools import partial >>> def spam(a, b, c, d): print(a, b, c, d) >>> s1 = partial(spam, 1) # a = 1 >>> s1(2, 3, 4) 1 2 3 4 >>> s2 = partial(spam, d=42) # d = 42 >>> s2(1, 2, 3) 1 2 3 42 >>> s3 = partial(spam, 1, 2, d=42) # a = 1, b = 2, d = 42 >>> s3(3) 1 2 3 42 >>>
排序使用示例:
"""將列表中的點根據距離基點的距離進行排序""" import math from functools import partial # 基點 pt = (4, 3) points = [(1, 2), (3, 4), (5, 6), (7, 8)] def distance(p1, p2): """返回兩個點之間的距離""" x1, y1 = p1 x2, y2 = p2 return math.hypot(x2 - x1, y2 - y1) points.sort(key=partial(distance, pt)) print(points) # [(3, 4), (1, 2), (5, 6), (7, 8)]
回調函數使用示例:
import logging from multiprocessing import Pool from functools import partial def output_result(result, log=None): if log is not None: log.debug('Got: %r', result) def add(x, y): return x + y if __name__ == '__main__': # logging模塊用於列印日誌 logging.basicConfig(level=logging.DEBUG) log = logging.getLogger('test') # 非同步調用另一個函數,並將log對象傳入進去 p = Pool() p.apply_async(add, (3, 4), callback=partial(output_result, log=log)) p.close() p.join()