装饰器轻松入门
什么是装饰器
简单理解装饰器, 就是以函数为参数, 以函数为返回值的函数就叫做装饰器. 简单示例如下:
def deco(func):
def inner():
print("this is inner func in decor.")
return inner
@deco
def target():
print('This is target func.')
target()
output:
this is inner func in decor.
以上操作与以下操作等价:
target = deco(target)
相当于, decorate函数接受target函数作为参数, 然后返回一个函数绑定在target变量上. 由以上可知装饰器的@func_name
是一语法糖(syntatic sugar). 所谓语法糖, 即是在计算机语言中, 添加的这种语法, 它不增加语言的功能, 只是起到使语言在使用中更方便, 可读性更强的作用.
叠放多个装饰器
可以对一个函数叠放多个装饰器, 如下例所示:
@d1
@d2
def f():
print('f')
其等价于:
def f():
print('f')
f = d1(d2(f))
让装饰器可以接收参数化
如果想要通过传入参数来控制, 调整装饰器的行为, 可以在装饰器的外面再包装一层函数, 该函数接受调整参数, 返回真正的装饰器函数, 该函数被称为装饰器工厂函数. 在调用时, 注意要以@deco_indystry(args)
形式, 即使不传入参数, 后面的()
也不能丢, 示例如下.
# registration_para.py
registry = set()
def register(active=True):
def decorate(func):
print("running register(active={})->decorate({})".format(active, func))
if active:
registry.add(func)
else:
registry.discard(func)
return func
return decorate
@register(active=False)
def f1():
print('running f1()')
@register()
def f2():
print('running f2()')
def f3():
print('runing f3()')
导入该模块, 有:
>>> import registration_para
running register(active=False)->decorate(<function f1 at 0x0000024AF4048940>)
running register(active=True)->decorate(<function f2 at 0x0000024AF4048EE0>)
查看registry变量中的函数:
>>> registration_para.registry
{<function f2 at 0x0000024AF4048EE0>}
可以看到, 该示例可以通过传入参数控制是否把被装饰的函数保存到变量registry中, 实际就起到了收集函数, 注册函数的目的.