python的裝飾器可以實現在**執行期間修改函式的上下文, 即可以定義函式在執行之前進行何種操作和函式執行後進行何種操作, 而函式本身並沒有任何程式設計客棧的改變。
這個看起來很複雜, 實際上應用到了我之前說過的閉包的概念, 仔細看一看, 其實並不複雜。
首先, 我們先定義乙個函式, 這個函式可以輸出我的個人暱稱:
def my_name():
print "yi_zhi_yu"
my_name() # yi_zhi_yu
那假如我需要在個人暱稱輸出前, 在vuugpaoe輸出我的個人uid呢, 當然, 要求是不改動現有的my_name函式, 這個時候就可以使用裝飾器了
首先, 裝飾器也是個函式, 其次, 他需要接受乙個引數,該引數表示了要被裝飾的函式(即my_name):
def my_info(func):
www.cppcns.comdef wrapper(*args, **params):
print 218
return func(*args, **params)
return wrapper
然後與相應的被裝飾函式關聯起來的方法就是使用@my_info寫在被裝飾函式的前面
@my_info
def my_name():
print "yi_zhi_yu"
最後, 在執行my_name的時候, 就能既輸出我的uid, 又能輸出我的暱稱了
my_name()
#218
#yi_zhi_yu
在上面, 最讓我們疑惑的是裝飾器函式定義裡面的wrapper函式, 裝飾器本身返回的是wrapper函式的定義, 而wrapper中則定義了對被裝飾函式(my_name)的呼叫, func表示的就是被裝飾函式, 說白了, 裝飾器只是把某個不得改動的函式(a)放到另乙個函式(b)中, 在b裡面呼叫a, 在呼叫前後就可以做所謂的看起來像裝飾的工作了。
my_info的最終返回的wrapper函式的定義, 並不是執行結果,只有當wrapper真正執行的時候, 才會真正的執行my_name方法, 這就是閉包時所說的內容。
wrapper中的引數, 實際上則是傳遞給func(實際上是my_name)的引數
因為裝飾器也是個函式, 那麼裝飾器自己的能不能有引數傳遞呢。可以, 不過需要定義乙個更高階的函式, 也就是外面還要套一層函式, 比如, 我還要輸出我的自定義的乙個資訊,需要傳遞引數
def c_info(text):
def my_info(func):
def wrapper(*args, **params):
print text
print 218
return func(*args, **params)
return wrapper
return my_info
#使用裝飾器
@c_info("tony")
def my_name():
print "yi_zhi_yu"
my_name()
#tony
#218
#yi_zhi_yu
與前面的那個裝飾器相比, 僅僅是多了個外層, 內層也僅僅是增加了對外層傳入引數(text)的呼叫
總而言之, python在函式定義中支援了對oop思想中的裝飾器的實現, 其本質也只是使用了閉包的思路, 延遲呼叫, 程式設計客棧並在呼叫前後增加自己的其他實現內容
本文標題: 簡單上手python中裝飾器的使用
本文位址: /jiaoben/python/127972.html
python中裝飾器
對修改是封閉的,對擴充套件是開放的 import time def f1 print time.time print this is a function.def f2 print this is a function.print time.time f1 def print current tim...
python中裝飾器詳解
最新學了裝飾器,有乙個疑問一直困擾我,思考了幾天,終於明白。首先,展示正常的裝飾器 允許向乙個現有的物件新增新的功能,同時又不改變其結構,就是給函式穿個衣服,但是不改變函式 該如何寫?def log func print call s func.name return func args,kw 依照...
python中裝飾器理解
裝飾器 decorators 是 python 的乙個重要部分。簡單地說 他們是修改其他函式的功能的函式。他們有助於讓我們的 更簡短!由於函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式。def now print 2015 3 25 f now f 2015 3 25 ...