马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 zltzlt 于 2020-1-23 20:27 编辑
Python 自定义装饰器
简而言之,Python 的装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数。
使用 Python 装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
Python 的内置装饰器有 property、classmethod 和 staticmathod。除了使用内置的装饰器我们还可以定义自己的装饰器。
先来看一个最简单的例子:
>>> def deco(func):
def wrapper(*args, **kwargs):
print("进入装饰器...")
func(*args, **kwargs)
print("离开装饰器...")
return wrapper
这里的 deco 函数就是装饰器,可以看到,deco 装饰器返回了一个 wrapper 函数。我们不妨来测试一下这个装饰器:
>>> @deco
def test():
print('testing...')
>>> test()
进入装饰器...
testing...
离开装饰器...
可以得知,装饰器参数中的 func 在这里就是 test。装饰器其实等同于:
>>> def test():
print('testing...')
>>> test = deco(test)
>>> test()
进入装饰器...
testing...
离开装饰器...
但是,细心的鱼油会发现,装饰器在一定程度上会破坏函数本身:
>>> print(test.__name__) # 应该是 'test'
wrapper
我们可以用 functools.wraps 装饰器解决这个问题:
>>> from functools import wraps
>>> def deco(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("进入装饰器...")
func(*args, **kwargs)
print("离开装饰器...")
return wrapper
>>> @deco
def test():
print('testing...')
>>> test()
进入装饰器...
testing...
离开装饰器...
>>> print(test.__name__)
test
学会了自定义简单的装饰器之后,我们可以编写一个计量代码用时的装饰器:
>>> import time
>>> def timeit(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
func(*args, **kwargs)
print('用时', time.perf_counter() - start, '秒')
return wrapper
测试:
>>> @timeit
def test():
s = 0
for i in range(10000):
s += i
>>> test()
用时 0.00043929999992542434 秒
|