Python裝飾器教程展示瞭如何在Python中使用裝飾器基本功能。
文章目錄
1 使用教程
Python函數是一等公民。這意味着函數與Python中的其他對象具有同等的狀態。可以將函數分配給變量,存儲在集合中,動態創建和刪除或作爲參數傳遞。嵌套函數也稱爲內部函數,指的是在另一個函數中定義的函數。
Python decorator擴展並修改可調用函數的行爲,而不修改可調用函數本身。decorator是修飾(或包裝)其他函數並在包裝函數運行前後執行代碼的函數。Python裝飾器通常用於日誌記錄,身份驗證和授權,計時和緩存中。
1.1 Python裝飾器簡單示例
在這個示例中,簡單創建一個簡單的裝飾器示例。
# 以函數作爲參數
def enclose(fun):
# wrapper*()用星好裝飾傳遞過來的函數,將返回包裝函數。
def wrapper():
print("***************************")
fun()
print("***************************")
# 返回包裝函數
return wrapper
# 這是要裝飾的常規函數
def myfun():
print("myfun")
# enclose()函數是類似decorator,它通過在輸出中添加星形符號來擴展myfun函數的輸出。
# myfun被傳遞給enclosure()函數,在該函數中對其進行了擴展。將返回並調用包裝函數。
enc = enclose(myfun)
# 調用包裝函數
enc()
***************************
myfun
***************************
1.2 帶@符號的Python裝飾器
Python允許使用@符號來標記要用decorator裝飾的方法。從功能上講,該示例與上一個示例相同。僅使用不同的語法。
def enclose(fun):
def wrapper():
print("***************************")
fun()
print("***************************")
return wrapper
# @enclose 就是enc = enclose(myfun)簡寫
# 表明調用enclose函數修飾myufun函數,並返回修飾函數
@enclose
def myfun():
print("myfun")
myfun()
***************************
myfun
***************************
1.3 用參數修飾函數
下面的示例演示如何裝飾帶有參數的函數。
def enclose(fun):
def wrapper(val):
print("***************************")
fun(val)
print("***************************")
return wrapper
@enclose
def myfun(val):
print(f"myfun with {val}")
myfun('falcon')
***************************
myfun with falcon
***************************
以下例子展示瞭如何使用*args,**kwargs語法處理可變數量的參數。
def enclose(fun):
def wrapper(*args, **kwargs):
print("***************************")
fun(*args, **kwargs)
print("***************************")
return wrapper
@enclose
def myfun(name, age):
print(f'{name} is {age} years old')
myfun(name='Peter', age=32)
myfun('Roman', 29)
***************************
Peter is 32 years old
***************************
***************************
Roman is 29 years old
***************************
1.4 Python裝飾器修改數據
decorator函數可以修改修飾函數的數據。
def uppercase(fun):
# 在包裝函數內部,修改並返回了文本
def wrapper():
res = fun()
modified = res.upper()
return modified
return wrapper
# @uppercase decorator將返回的文本更改爲大寫
@uppercase
def gen_message():
return 'Hello there!'
msg = gen_message()
print(msg)
HELLO THERE!
1.5 Python多層裝飾器
可以在一個函數上應用多個裝飾器。以下示例在文本上應用了兩個HTML標籤。
def strong(fun):
def wrapper():
return f'<strong>{fun()}</strong>'
return wrapper
def em(fun):
def wrapper():
return f'<em>{fun()}</em>'
return wrapper
# 先調用em裝飾器,再調用strong裝飾器
@strong
@em
def message():
return 'This is some message'
print(message())
<strong><em>This is some message</em></strong>
1.6 Python裝飾器計時示例
在下面的示例中,我們在函數上應用計時器裝飾器。下面示例使用decorator計算factoria()函數運行的時間。
import time
import math
def timer(func):
def wrapper(*args, **kwargs):
# 在函數運行之前,我們獲得了開始時間。
begin = time.time()
f = func(*args, **kwargs)
# 獲得結束時間
end = time.time()
print("Total time taken in : ", func.__name__, end - begin)
return f
return wrapper
@timer
def factorial(num):
return math.factorial(num)
f = factorial(4580)
Total time taken in : factorial 0.0005843639373779297