Decorator 是 Python 中特殊的 Function 使用方式,
使用時機是在執行某些Function 之前會有固定動作會執行的時候,
可以將這些動作拉出來做Decorator,
例如登入前的權限檢查,
在Flask中的route 的 @app.route('route') 就是Decorator的使用,
最基本的Decorator
def decorator(f):
print("Enter decorator")
return f;
@decorator
def Function(arg):
print "Enter Function,arg=",arg
Function(1)
Function(100)
"""
res:
Enter decorator
Enter Function,arg= 1
Enter Function,arg= 100
"""
雖然上例有調用Decorator,
但是只有第一次的時候有調用而第二次之後就沒有了,
這似乎和我們所要的還是有一點差距,
我們再把程式作一些小修改。
def decorator(f):
print("Enter decorator")
def wrapper(arg):
print("Enter wrapper!")
return f(arg)
return wrapper;
@decorator
def Function(arg):
print "Enter Function,arg=",arg
Function(1)
Function(100)
"""
res:
Enter decorator
Enter wrapper!
Enter Function,arg= 1
Enter wrapper!
Enter Function,arg= 100
"""
在裡面多加一層wrapper 並且將所需要重複執行的程式放寫在wrapper裡面,
每次執行的時候就會自動將裡面的程式碼執行一次達到我們所需要的效果。
其實我們將上述的程式作一些小小的搬動
def decorator(f):
print("Enter decorator")
def wrapper(arg):
print("Enter wrapper!")
return f(arg)
return wrapper;
def Function(arg):
print "Enter Function,arg=",arg
<strong>Function = decorator(Function) </strong>
Function(1)
Function(100)
結果兩個結果都是一樣的,
所謂的Decorator只是多做了在Function 外面多包上一層wrapper,
當我們使用這個Function 的時候自然就會先呼叫外層的Wrapper 而達到我們需要的效果。
Decorator既然是Function 的一種使用方式,
那麼我們要如何在Decorator 丟參數進去wrapper,
可以讓我們使用上更加彈性呢?
#-*- coding:utf-8 -*-
def say(worker):
print 'I am worker %s' % worker
def dec(fn):
def wraped(*argv,**kwgs):
print 'staring..'
fn(*argv,**kwgs)
print 'end.'
return wraped
return dec
@say("maind")
def main(n):
for i in range(n):
print i*2
if __name__ == "__main__":
#@say(argv) 实际上等同于 main=say(argv)(main)
main(10)
其實就是在Decorator 上面在包覆一層Function 提供丟入參數,
其餘的並不改變。
Decorator 在 Python 中扮演著相當重要的角色,
多練習寫幾個 Decorator甚至在自己的程式中嘗試加入,
會讓你更加了解它的特色與使用,
然後就發現其實並沒有那麼複雜了!