Python之装饰器
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能
,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
它可以装饰的东西有:函数、类
由以下例子来讲述,
part1简单装饰器
假如说我们由一个需求,计算两个数字的和
def sum(x, y):
print ("The sum is: " + str(x + y))
现在我们需要对需求加以改进,加上函数执行的时间。
那么不使用装饰器的代码,我们可能会按以下方式实现:
In [11]: import time
In [12]: def sum(x, y):
...: begin_time = time.time()
...: value = x + y
...: print ("The time cost is: %s " %(time.time() - begin_time))
...: return value
...:
但是这时候,我们发现,代码不是很和谐。 不符合pythonic。
那么这时候,我们可以使用装饰器了
# 先定义一个装饰器
def time_cost(func):
def wrapper(x, y):
begin_time = time.time()
value = func(x, y)
print("The time cost is %s" %(time.time() - begin_time))
return value
return wrapper
# 使用装饰器
@time_cost
def sum(x, y):
return x + y
这时候我们再次调用sum()
函数时,跟刚开始我们实现的结果一样,但是对于我们的代码而言,却更加的简洁,工整。
part2 带参数的装饰器
我们也可以对装饰器加上参数。
我们以另一个例子来解释:
def use_logging(level):
def decorator(func):
def wrapper(*args, **kwargs):
if level == "warn":
logging.warn("%s is running" % func.__name__)
return func(*args)
return wrapper
return decorator
@use_logging(level="warn")
def foo(name='foo'):
print("i am %s" % name)
在上述的use_logging
是允许带参数的装饰器。它实际上是对原有装饰器的一个函数封装,并返回一个装饰器。我们可以将它理解为一个含有参数的闭包。当我们使用@use_logging(level="warn")
调用时。可以解释器可以发现这一层封装,并把参数传递到装饰器的环境中。
part3 内置装饰器
内置装饰器主要有三个 @staticmathod、 @classmethod、 @property。
对于前两者:
- 两者的区别在于@classmethod的第一个参数会默认为calculations这个类。
而@property的作用主要是提供一个把类方法变成类属性的方法。
比如可以把@property用作getter和setter。
以上,是简单的总结。
参考资料: