python裝飾器原理和用法總結


原理

裝飾器本質也是一個函數, 只不過這個函數需要遵循以下規則:

  • 入參只能有一個,類型為函數。 被裝飾的函數將入會被傳入這個參數
  • 返回值是必須是一個函數, 屆時被調用的時候實際上調用的是返回出來的這個函數,所以返回的函數入參通常是
(*args, **kwargs):

以滿足所有函數需要

之后通過@語法糖即可裝飾到任意函數上

簡單裝飾器例子

# 不帶參數的裝飾器
def pre_do_sth(func):
    def wrapper(*args, **kwargs):
        print("Do sth before call one")
        func(*args, **kwargs)
    return wrapper
  
@pre_do_sth
def echo(msg):
    print(msg)
    
echo("Hello World")

運行結果

Do sth before call one
Hello World

實際上調用的是 wrapper("Hello World") --> echo("Hello World")

帶參數的裝飾器例子(參數控制的是裝飾器的行為)

只需要寫一個返回 裝飾器(入參只有一個, 返回值是一個函數)函數的函數

同樣也能利用@語法糖

# 帶參數的裝飾器
def pre_do_sth_2(msg):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print("Do sth before call two, print:%s"%(msg))
            func(*args, **kwargs)
        return wrapper
    return decorator


@pre_do_sth_2("Foo")
def echo(msg):
    print(msg)

echo("Hello World")

實際上@后面並不是對pre_do_sth_2這個函數生效 而是對pre_do_sth_2的返回值生效

運行結果

Do sth before call two, print:Foo
Hello World

多個裝飾器調用順序

先聲明的裝飾器先執行, 即在最外層

# 不帶參數的裝飾器
def pre_do_sth(func):
    def wrapper(*args, **kwargs):
        print("Do sth before call one")
        func(*args, **kwargs)
    return wrapper

# 帶參數的裝飾器
def pre_do_sth_2(msg):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print("Do sth before call two, print:%s"%(msg))
            func(*args, **kwargs)
        return wrapper
    return decorator


@pre_do_sth
@pre_do_sth_2("Foo")
def echo(msg):
    print(msg)

echo("Hello World")

運行結果

Do sth before call one
Do sth before call two, print:Foo
Hello World


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM