本篇文章帶給大家的內容是關於Python中裝飾器是什麼? Python中裝飾器的介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
裝飾器,decorator,本質上是一個Python函數,它可以讓其他函數在不需要做任何程式碼變動的前提下增加額外功能,裝飾器的回傳值也是函數物件。
裝飾器透過不修改核心程式碼而增強核心程式碼部分的功能。例如在函數前插入日誌、權限校驗、交易處理等場景。
而且可以抽離出大量與函數功能無關的雷同程式碼並重複使用。
#Python中函數也可以看做是一個對象,可以賦值給變量,並透過變數呼叫該函數。
例如:
def foo(): print("2017-06-08") f = foo # 将函数赋值给变量,f为函数对象 f() # 返回结果: 2017-06-08
假設現在要增強foo()的功能,例如,在函數呼叫前列印日誌。但是又不希望修改foo()函數的定義。在這種程式碼運作期間動態增加功能的方式,稱之為「裝飾器」。
如下:
def testfunc(func): print('testfunc') def wrapper(): print("%s %s() called" %(time.ctime(),func.__name__)) return func() return wrapper @testfunc def foo(): print('foo1()') foo() # 相当于执行testfunc(foo) ->wrapper(foo) -> foo()
執行結果:
testfunc Wed Sep 12 15:01:13 2018 foo() called foo1()
說明:執行foo()前,先執行testfunc(foo),再執行wrapper(),在返回時呼叫foo()本身。
#裝飾器可以接收參數,當呼叫裝飾器傳回的函數時,也就呼叫了包裹函數,把參數傳入包裹函數,它將參數傳遞給被裝飾的函數。
如下:
def testfunc_with_args(func): def wrapper_argus(arg1, arg2): print("I got args! Look:", arg1, arg2) func(arg1, arg2) return wrapper_argus @testfunc_with_args def full_name(first_name, last_name): # 带参数,将参数传给被装饰的函数 print("My name is", first_name, last_name) full_name("Peter", "Venkman") # 调用
執行結果:
I got args! Look: Peter Venkman My name is Peter Venkman
當有多個函數需要呼叫裝飾器,但是函數的參數各不同時,該如何實現呢?總不能一個函數對應一個裝飾器吧。這時候就可以用不定參數的裝飾器來實現。
如下:
def log(func): def wrapper(*args,**kwargs): # 可接受各种参数 print('call %s():'% func.__name__) return func(*args,**kwargs) # 返回一个函数 return wrapper # 装饰器返回一个函数,进入到wrapper() @log # @log放到now()的定义处,相当于执行语句:now = log(now) def now_1(a,b): print('now()1:a+b = ',a+b) @log def now_2(a,b,c): print('now_2():a+b+c = ',a+b+c) now_1(1,2) now_2(1,2,3)
執行一下喔~
當一個函數想要加入多項功能時,可以考慮使用多層裝飾器,就是要注意一下裝飾器的執行順序。
舉個栗子:
# 注意代码的执行顺序 def deco_1(func): print('------111111------') def wrapper(*args,**kwargs): # 包裹函数,参数与原函数的参数一致 print('start: this is deco_1.') func(*args,**kwargs) print('end: deco_1.') return wrapper # 返回值是一个包裹函数 def deco_2(func): print('------222222------') def wrapper(*args,**kwargs): print('start: this is deco_2.') func(*args,**kwargs) print('end: deco_2.') return wrapper @deco_1 @deco_2 def now_1(a,b): print('now()1:a+b = ',a+b) now_1(1,2)
運行結果:
# 结果,注意执行顺序: ------222222------ ------111111------ start: this is deco_1. start: this is deco_2. now()1:a+b = 3 end: deco_2. end: deco_1.
除了給被裝飾的函數帶參數,裝飾器本身也可以帶參數。
def logging(level): def wrapper(func): def inner_wrapper(*args, **kwargs): print("[{level}]: enter function {func}()".format(level=level, func=func.__name__)) return func(*args, **kwargs) return inner_wrapper return wrapper @logging(level='INFO') def say(something): print("say {}!".format(something)) @logging(level='DEBUG') def do(something): print("do {}...".format(something)) say('hello') do("my work")
執行結果:
# 执行结果: [INFO]: enter function say() say hello! [DEBUG]: enter function do() do my work...
相關推薦:
###################################################################### Python中的各種裝飾器詳解######以上是Python中裝飾器是什麼? Python中裝飾器的介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!