Python中的装饰器
- 装饰器:本质就是一个函数,主要是为其他函数添加附加功能
- 原则:不修改被修饰函数的源代码,不修改被修饰函数的调用方式。
简单示例
- 加的原来一个加法器如下:
def add(x,y):
print("开始计算{}+{}".format(x,y))
hh = x + y
print("结果为:{}".format(hh))
return hh
- 现在需要在不改变原代码的情况下,不修改调用方式的情况下,对加法运算前后增加相应功能
简单示实现如下:
#原加法器
def add(x,y):
print("开始计算{}+{}".format(x,y))
hh = x + y
print("结果为:{}".format(hh))
return hh
def strengthen(fn):
def _add(*args,**kwargs):
print("加法前执行")
fn(*args,**kwargs) #这里使用原理的加法器做运算
print("加法后执行")
return _add
add = strengthen(add)
add(5,4)
decorator
- 上面代码中strengthen方法就对add加法器进行了装饰。
装饰器语法
- 在python中提供了一种语法糖,来方便使用者实现上述这种装饰功能。
简单代码如下:
def strengthen(fn):
def _add(*args,**kwargs):
print("加法前执行")
fn(*args,**kwargs) #这里使用原理的加法器做运算
print("加法后执行")
return _add
#表示用strengthen装饰add方法
@strengthen #注意@strengthen 等价于 add = strengthen(add)
def add(x,y):
print("开始计算{}+{}".format(x,y))
hh = x + y
print("结果为:{}".format(hh))
return hh
add(5,4)
装饰器语法糖,【@+表达式】
@表达式
函数
等价于 函数名 = 表达式执行结果(函数名)
- 注意:表达式的返回值一定要是一个函数。
例如:
import datetime,time
#定义修改注解函数,并将修改注解函数柯里化
def logg(fn):
def copy_property(tofn):
tofn.__name__ = fn.__name__
tofn.__doc__ = fn.__doc__
return tofn #注意,这里需要将原函数返回。不然元函数值为none
return copy_property
def strengthen(fn):
"""我是strengthen方法的注解"""
@logg(fn) #等效于 wrapper = logg(fn)(wrapper)
def wrapper(*args,**kwargs):
"""我是wraper方法的注解"""
starttime = datetime.datetime.now()
fn(*args,**kwargs) #这里使用原理的加法器做运算
elapsedtime = datetime.datetime.now() - starttime
print("耗时:{}".format(elapsedtime.total_seconds()))
return wrapper
@strengthen #等效于add = strengthen(add)
def add(x,y):
"""我是add方法的注解"""
print("开始计算{}+{}".format(x,y))
time.sleep(1)
hh = x + y
print("结果为:{}".format(hh))
return hh
add(5,4)
print(add.__name__)
# datetime.datetime.now()
- 运行结果为:
- 上面示例中,不仅对add函数做了装饰,而且还改变了装饰器的默认属性与add属性保持一致。