功能:
為已存在的函數或對象添加額外的功能
?
原則:
- 不改變源代碼為其添加功能
- 不改變函數的調用方式
?
方法:
裝飾器 = 高階函數 + 嵌套函數
(高階函數:一個函數可以作為參數傳遞給另外一個函數,或者,一個函數的返回值是一個函數,即函數的入口地址)
- 函數名作為參數傳遞給裝飾器(@decorator_name)
- 裝飾函數返回函數名(函數地址)
注意:
- 默認情況下,裝飾器會修改名字和文檔說明,但是可以使用 functools 中 的 @wraps() 解決。@wraps接受一個函數來進行裝飾,并加入了復制函數名稱、注釋文檔、參數列表等等的功能。這可以讓我們在裝飾器里面訪問在裝飾之前的函數的屬性。
def decorator(func):
"""
decorator __doc__
"""
# @wraps(func)
def wrapper(*args, **kwargs):
"""wrapper __doc__"""
func()
return wrapper
@decorator
def test():
"""test __doc__"""
time.sleep(0.5)
test(1, 2)
print("function name:", test.__name__)
print("function doc :", test.__doc__)
# output:
# function name: wrapper
# function doc : wrapper __doc__
# 加了@wraps(func)后的output:
# function name: test
# function doc : test __doc__
?
?
例子:
1. 函數作為裝飾器
此例子實現了一個計算調用函數所占用的時間
import time
from functools import wraps
def decorator(func):
"""
function:decorator
"""
@wraps(func)
def wrapper(*args, **kwargs):
"""function:wrapper"""
start = time.time()
ret = func(*args, **kwargs)
end = time.time()
print("function {0} run time: {1}".format(func.__name__, end - start))
# print("function {fun} run time: {time}".format(fun=func.__name__, time=end - start))
return ret
return wrapper
@decorator
def test(a, b, name="Lizo"):
"""function:test"""
time.sleep(0.5)
print(a, b, name)
2.類作為裝飾器
為什么可以使用類作為裝飾器?因為在Python中,一切皆對象,其實函數也是一個對象,如果一個類實現了? __call__(self) 方法后,就可以像調用函數一樣,直接加一個括號就可以調用。
class Runtime:
def __init__(self):
pass
def __call__(self, func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
ret = func(*args, **kwargs)
end = time.time()
print("function: {func} run time: {time}".format(func=func.__name__, time=end - start))
return ret
return wrapper
#使用裝飾器方法1
runtime = Runtime()
@runtime
def test_class_decorator1():
print("in the test_class_decorator")
time.sleep(0.2)
#使用裝飾器方法2
@Runtime()
def test_class_decorator2():
print("in the test_class_decorator")
time.sleep(0.2)
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
