【函數】04、裝飾器
阿新 • • 發佈:2017-06-17
裝飾器
一、高階函數
python中函數是一等對象(first class);函數也是對象,並且它可以像普通對象一樣復制、作為參數、作為返回值。
返回函數或者參數是函數的函數就是高階函數,也被稱為函數式編程
In [23]: def counter(base): ...: def inc(x=1): ...: nonlocal base ...: base += x ...: return base ...: return inc # 返回一個函數 ...: In [24]: inc = counter(3) In [25]: inc Out[25]: <function __main__.counter.<locals>.inc> In [26]: inc() Out[26]: 4 In [27]: inc() Out[27]: 5
內置函數sorted()的實現:
In [48]: def sort(it, cmp=lambda a, b: a<b): ...: ret = [] ...: for x in it: ...: for i, e in enumerate(ret): ...: if cmp(x, e): ...: ret.insert(i, x) ...: break ...: else: ...: ret.append(x) ...: return ret ...: In [49]: sort([1, 3, 5, 2, 4, ]) Out[49]: [1, 2, 3, 4, 5] In [50]: sort([1, 3, 5, 2, 4, ], lambda a, b: a>b) Out[50]: [5, 4, 3, 2, 1]
總結:
函數作為返回值常用於閉包的場景:需要封裝一些變量
函數作為參數常用於大多數邏輯固定,少部分邏輯不固定的場景
函數作為參數,返回值也為是函數:常用於作為參數的函數在執行前後需要一些額外的操作(增加功能)
In [77]: def add(x, y): ...: return x + y ...: In [78]: add.__name__ Out[78]: ‘add‘ In [80]: def logger(fn): ...: def wrap(*args, **kwargs): ...: print(‘call {}‘.format(fn.__name__)) ...: ret = fn(*args, **kwargs) ...: print(‘{} called‘.format(fn.__name__)) ...: return ret ...: return wrap ...: In [81]: loged_add = logger(add) In [82]: loged_add(3, 5) call add add called Out[82]: 8
簡單、優雅一點:
In [90]: def add(x, y): ...: return x + y ...: In [91]: def logger(fn): ...: def wrap(*args, **kwargs): ...: print(‘call {}‘.format(fn.__name__)) ...: ret = fn(*args, **kwargs) ...: print(‘{} called‘.format(fn.__name__)) ...: return ret ...: return wrap ...: In [92]: add = logger(add) # add變量名被重新賦值定義,賦值是先執行右邊的部分 In [93]: add(3, 4) call add add called Out[93]: 7
更簡單、優雅:
In [102]: def logger(fn): ...: def wrap(*args, **kwargs): ...: print(‘call {}‘.format(fn.__name__)) ...: ret = fn(*args, **kwargs) ...: print(‘{} called‘.format(fn.__name__)) ...: return ret ...: return wrap ...: In [103]: @logger # @這是裝飾器的語法糖,相當於 add=logger(add)=wrp ...: def add(x, y): ...: return x + y ...: In [104]: add(1, 2) call add add called Out[104]: 3
這是logger就是裝飾器了
二、裝飾器
1、裝飾器
函數的參數是一個函數,返回值也是一個函數,就可以作為裝飾器
【函數】04、裝飾器