首頁 >後端開發 >Python教學 >Python中裝飾器是什麼? Python中裝飾器的介紹

Python中裝飾器是什麼? Python中裝飾器的介紹

不言
不言原創
2018-09-13 16:50:242938瀏覽

本篇文章帶給大家的內容是關於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中裝飾器是什麼? Python中裝飾器的介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn