消除裝飾器對原函式的屬性影響
阿新 • • 發佈:2020-12-29
首先介紹Python的"萬能"裝飾器模版:
import os def decor(func): def with_decor(*args, **kwargs): #這裡內部巢狀函式使原函式引數能順利傳遞 func(*args, **kwargs) #func_A 會在這裡被呼叫 a = args print(a) print('call decor') return with_decor @decor def func_A(*args, **kwargs): print('call A') func_A(1,2,3) os.system("pause")
該程式將會輸出:
呼叫 func_A 函式會執行直接裝飾器裡的內容,並將引數傳入閉包
然後介紹一下這種一般裝飾器的副作用:
python裝飾器會使原函式的屬性被改變,比如func.__name__
這裡新增一行 print(func_A.__name__)來展示影響
輸出效果:
可以看到原函式 func_A的名字變成了裝飾器裡面的函式with_decor的名字
這導致一些特殊場合要用到這些屬性時不方便,比如在 Robot Framework自動化測試框架中呼叫函式,函式被裝飾後就不能被正常呼叫
因此可採用from functools import wraps,避免這種影響:
import os from functools import wraps def decor(func): @wraps(func) def with_decor(*args, **kwargs): return func(*args, **kwargs) return with_decor @decor def func_A(*args, **kwargs): print('call A') func_A(1,2,3) print(func_A.__name__) os.system("pause")
輸出: 可以看到原函式的屬性沒有被改變
wraps 的作用可以理解為消除裝飾器的影響