python的裝飾器是乙個函式b 用來裝飾另乙個函式a(使a具有b的功能,執行a方法同時 也會執行b方法)
這種用法用到 : 內部函式 、 函式傳遞
沒有使用@
def debug(func):
print 1111
#內部函式返回 入參函式 並執行
return func()
print 2222
# 裝飾器函式返回 內部函式 並執行
#函式在返回的時候被執行 先執行裝飾器的內部函式 再執行被裝飾的函式
def say_hello():
print 3333
print "hello!"
print 4444
say_hello = debug(say_hello)
#新的say_hello方法擁有了 debug的方法 debug函式就是裝飾器
say_hello()
#不帶括號時,呼叫的是這個函式本身,是整個函式體,
#帶括號時,呼叫的是函式執行的結果
結果如下
2222
1111
3333
hello!
4444
使用@
def debug(func):
print 1111
#內部函式返回 入參函式
return func()
print 2222
# 裝飾器函式返回 內部函式
@debug
def say_hello():
print 3333
print "hello!"
print 4444
say_hello()
執行的結果是一樣 同上所以: @debug <==> say_hello = debug(say_hello)
再來討論 有引數的裝飾器
這裡的有引數值的是被裝飾的函式,相應的裝飾器內部返回函式為了保持一致,也要新增引數
有@
def debug(func):
#say_hello("******") 函式傳遞進入debug
print 4
#內部函式返回 入參函式
print 3
# 裝飾器函式返回 內部函式
@debug
def say_hello(a):
print 1
print a
print 2
say_hello("******")
結果如下
341
******
2分析結果:
1、執行
say_hello("******") 帶入參的方法 進入裝飾器函式debug 順序執行 先列印 3 在 return wraper時候進入 wraper(a)
列印4 再在 return func(a) 進入執行被裝飾 函式 say_hello("******") 順序列印 1 ****** 2 執行完畢
帶引數的不用@的時候
def debug(func):
#say_hello("******")
print 4
#內部函式返回 入參函式
return func(b)
print 2
print 3
# 裝飾器函式返回 內部函式
# @debug
def say_hello(a):
print 1
print a
print 2
say_hello = debug(say_hello)("******")
執行結果如上 ,具體執行順序 琢磨一下
也可以比較下 下面兩種不同的宣告方法 得到什麼樣的結果 為什麼??
say_hello = debug(say_hello("******"))
say_hello = debug(say_hello)("******")
另得一下結論:以下三種裝飾器的使用是等效的 輸出的結果是一樣的
@debug
say_hello("******")
<==>
debug(say_hello)("******")
<==>
say_hello = debug(say_hello)
say_hello("******")
推薦這裡參考學習 Python 裝飾器筆記
def wrap in tag b fn wrap in tag b 是真正的裝飾器 def return fn return defwrap in tag i fn def return fn return wrap in tag b wrap in tag i defhello return h...
Python 裝飾器筆記
def wrap in tag b fn wrap in tag b 是真正的裝飾器 def return fn return defwrap in tag i fn def return fn return wrap in tag b wrap in tag i defhello return h...
Python 學習筆記 裝飾器
裝飾器也是乙個函式 巢狀 用來裝飾某個函式,來看下面的 import time deftime count func def start time.time func end time.time print this funnction costs end start deftellhi print...