python裝飾器:有引數的裝飾器、不定長引數的裝飾器、裝飾有返回值的函式、通用的裝飾器
阿新 • • 發佈:2018-12-19
將一個函式作為另一個函式的引數,返回值賦給這個函式
def func(funcname):
print("----fun 1---")
def fun_in():
print("----fun_in----1")
funcname()
print("----fun_in----2")
print("----func2-----")
return fun_in
def test():
print("----test----")
test=func(test)
test()
#上面的執行結果: '''執行結果 ----fun 1--- ----func2----- ----fun_in----1 ----test---- ----fun_in----2 '''
上面是之前學過的函式的使用,這裡我們採取裝飾器的方式達到相同的效果
#前面對test的使用用到了test=func(test),可以使用裝飾器來達到相同的效果
@func
def test2():
print('----test2----')
test2()
'''執行結果
----fun 1---
----func2-----
----fun_in----1
----test2----
----fun_in----2
'''
考慮多種情況的裝飾器:
1.有引數的裝飾器
def funcProperty(funcname): print("----funPro 1---") def fun_in(a,b):#test(2,0)呼叫的是這個函式,需要有兩個引數 print("----fun_in----1") funcname(a,b)#這裡的test(2,0)作為引數傳遞進來,需要有兩個引數 print("----fun_in----2") print("----funcPro2-----") return fun_in @funcProperty def test(a,b): print("----the property is %d,%d----"%(a,b)) test(2,0)
'''執行結果
----funPro 1---
----funcPro2-----
----fun_in----1
----the property is 2,0----
----fun_in----2
'''
2.不定長引數
#對於不定長引數的函式的處理 def funcPro(funcName): print("---不定長引數的傳遞---") def func_in(*args,**kwargs):#前面傳遞的是元組,後面是字典 print("----args,kwargs---") funcName(*args,**kwargs) print("-----end args ,kwargs----") print("---不定長引數傳遞結束--") return func_in @funcPro def testThree(a,b,c): print("----test a=%d,b=%d,c=%d----"%(a,b,c)) testThree(1,2,3) #這裡引數傳遞幾個值,都可以,跟test對應起來就可以
'''執行結果
----funPro 1---
----funcPro2-----
---不定長引數的傳遞---
---不定長引數傳遞結束--
----args,kwargs---
----test a=1,b=2,c=3----
-----end args ,kwargs----
'''
3.對帶有返回值的函式進行裝飾
#再次分析:上面進行裝飾的時候,已經把testThree作為 引數傳遞過去,下面testThree(1,2,3)執行的時候,就是呼叫func_in
#testThree(1,2,3)指向的就是func_in,func_in中的funcName就呼叫了testThree(a,b,c)的內容
#使用裝飾器對帶有返回值的函式進行裝飾
#
def funcReturn(functionName):
print("---有返回值的函式---")
def func_in():
print("--先進行裝飾,將有返回值的函式作為引數傳遞進來")
res=functionName()
print("--呼叫有返回值的函式後--")
return res
print("---有返回值的函式裝飾結束---")
return func_in
@funcReturn
def testRe():
print("---這個函式有返回值")
return "測試有返回結果"
ret=testRe()
print("the end value is %s"%ret)
'''執行結果
---有返回值的函式---
---有返回值的函式裝飾結束---
--先進行裝飾,將有返回值的函式作為引數傳遞進來
---這個函式有返回值
--呼叫有返回值的函式後--
the end value is 測試有返回結果
'''
根據前面的幾種情況我們可以考慮設計一個通用的裝飾器:
#一個通用的裝飾器
def funcAll(funcName):
def func_in(*args,**kwargs):
ret=funcName(*args,**kwargs)
return ret
return func_in
#這個通用的裝飾器,有無返回值都可以,沒有返回值的話,ret=None,引數的話採用不定長引數
我們可以根據裝飾器的函式的引數不同,進行不同的操作
#帶有引數的裝飾器
def func_arg(arg):
def funcAll(funcName):
def func_in(*args,**kwargs):
if arg=="2":#根據裝飾的引數不同,可以進行不同的處理
ret=funcName(*args,**kwargs)
ret=funcName(*args,**kwargs)
else:
ret=funcName(*args,**kwargs)
print("arg is %s"%arg)
return ret
return func_in
return funcAll
#執行分析:
#1 先執行func_arg("hello")函式,這個函式return的結果是func這個函式的引用
#2 @func_arg("hello")----->@funcAll
#3 使用@func對testArg()進行裝飾
@func_arg("hello")
def testArg():
print("---帶有引數的裝飾器---")
@func_arg("2")
def testArg2():
print("---帶有引數的裝飾器---")
testArg()
testArg2()
'''執行結果
---帶有引數的裝飾器---
arg is hello
---帶有引數的裝飾器---
---帶有引數的裝飾器---
arg is 2
'''
#帶有引數的裝飾器,在執行中可以根據引數進行不同執行