【Python】四、装饰器
在一些反复使用的语句或函数的应用场景时,修改的封闭性不能很好地保证,或者不够优雅,装饰器解决了这一问题
例如,当我们想知道程序的运行时间时,在开始运行前获取一个时间戳,运行结束时获取一个时间戳,两者做差,能够得出程序的运行时间,需要每次调用函数时,在首尾都要添加获取时间戳函数,之后做差,一旦修改需求,就会很麻烦,我们可以使用装饰器
装饰器的实质与闭包类似,其中体现了函数是一个对象,可以传入作为参数
import time
def decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print("running time:" + str(end - start))
return wrapper
def func(n):
sum = 0
for i in range(n):
sum += i
f = decorator(func)
f(10000)
装饰器的python语法糖,让这样的格式变得方便,上下两者等价
import time
def decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print("running time:" + str(end - start))
return wrapper
@decorator
def func(n):
sum = 0
for i in range(n):
sum += i
func(100000)
装饰器语法
def decorator(func):
def wrapper(*args,**kwargs):
...
func(*args,**kwargs)
return wrapper
-
将
wrapper
封装起来 -
可以用
@+装饰器名称
调用,不影响原函数的调用
装饰器的问题
实际上,添加装饰器的函数,已经不是原来的函数了,在过程中改变,可以通过运行func.__name__
看出,结果为wrapper
可以通过调用functools
中的wraps
可以保留原函数的名字和文档
import time
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print("running time:" + str(end - start))
return wrapper
@decorator
def func(n):
sum = 0
for i in range(n):
sum += i
func(100000)
print(func.__name__)
此时__name__
结果为func