這篇我們繼續說裝飾器,之前裝飾器的例子都是不帶參數的例子,但我們經常也見到很多裝飾器是有參數的,如果你接觸過Flask web框架,你應該對它的路由實現不陌生,它就是用裝飾器來實現的,例如:
@app.route('/foo')def foo(): return 'ok'
在說裝飾器參數前,我們先看一個不帶參數的例子,然后逐步分析看如何傳遞參數,簡單的代碼如下:
def comm_decorator(f): def wrapped(*args, **kwargs): print('開始運行函數') response = f(*args, **kwargs) print('函數運行完畢') return response print(f) return wrapped
@comm_decoratordef fun1(a, b): print('fun1 函數') return a + b
fun1()
輸出:
以上的例子,我們在用裝飾器的時候沒傳參數進去,但實際上裝飾器會把他裝飾的函數傳遞進去,而且是整個作為一個參數進行傳遞,所以如果你認為簡單的在裝飾器調用的時候加個參數進去,是不行的,會直接報錯,因為裝飾器需要的是一個函數作為參數傳進去,所以這么看是沒辦法直接傳遞的,咋辦?
我們先看下裝飾器調用方式,上面的方式跟下面的方式是一樣的:
comm_decorator(fun1)
這個大家應該都知道了,那怎么把參數傳遞進去,如果我們的裝飾器返回的是一個裝飾器函數,然后再把我們的要裝飾的函數傳遞進入,就實現了我們參數的傳遞,像這樣的方式調用,看大家是否理解。
comm_decorator(arg)(fun1)
如果理解了上面的調用方式,接下來就是代碼實現了,比如我們要是實現一個可傳數字的裝飾器,傳遞的數字表示函數執行幾次,代碼如下:
def exec_many(n): def inner_decorator(fun): def wrapped(*args, **kwargs): for i in range(n): fun(*args, **kwargs) return wrapped return inner_decorator
@exec_many(3)def fun1(): print('in fun1') fun1()
輸出:in fun1in fun1in fun1
代碼分析,在這里我們定義了一個exec_many的裝飾器,它接受一個數字參數,這個參數用來決定執行多少次函數,然后在函數內部定義了一個inner_decorator函數,可以簡單理解是個內部裝飾器函數,在這個函數下的代碼就跟上面不帶參數的一樣了,最后看看函數返回什么?返回的是inner_decorator,就是把裝飾器返回了,所以它返回的是個裝飾器,再看它的調用方式,就容易理解的多:
exec_many(3)(fun1)
這篇就分享到這里,覺得有用的可以點個"
作者: Python運維技術 python運維技術
來源公眾號:
python運維技術
聲明:
本站(www.rxbbx.com)部分圖文轉自網絡,刊登本文僅為傳播信息之用,絕不代表贊同其觀點或擔保其真實性。若有來源標注錯誤或侵犯了您的合法權益,請作者持權屬證明與本網聯系,我們將及時更正、刪除,謝謝