原理
裝飾器本質也是一個函式, 只不過這個函式需要遵循以下規則:
- 入參只能有一個,型別為函式, 被裝飾的函式將入會被傳入這個引數
- 回傳值是必須是一個函式, 屆時被呼叫的時候實際上呼叫的是回傳出來的這個函式,所以回傳的函式入參通常是
(*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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/150261.html
標籤:Python
