为已存在的函数或对象添加额外的功能
装饰器 = 高阶函数 + 嵌套函数
(高阶函数:一个函数可以作为参数传递给另外一个函数,或者,一个函数的返回值是一个函数,即函数的入口地址)
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__
此例子实现了一个计算调用函数所占用的时间
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)
为什么可以使用类作为装饰器?因为在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)