Python 函数装饰器可以把被装饰的函数替换为另一个函数。
1 基础
def deco(func):
def inner():
logging.info('inner -> %s','running')
return inner
@deco
def target():
logging.info('target -> %s', 'running')
target()
logging.info('target -> %s',target)
运行结果:
- 这个示例首先定义了一个名为 deco 的函数,其内部定义了一个 inner 的内部函数,然后返回这个内部函数;
- 接下来,使用函数装饰器语法,装饰了名为 target 的函数;
- 最后调用 target 函数。
可以看到实际调用的是 inner() 函数,也就是 target 函数被替换成了 inner 函数。
2 运行模式
定义被装饰函数的代码处,就会执行该装饰器。
registry = []
def register(func):
logging.info('[register] func -> %s', func)
registry.append(func)
return func
@register
def f1():
logging.info('f1 -> %s', f1)
@register
def f2():
logging.info('f2 -> %s', f2)
def f3():
logging.info('f3 -> %s', f3)
def main():
logging.info('main -> %s', main)
logging.info('registry -> %s', registry)
f1()
f2()
f3()
if __name__ == '__main__':
main()
运行结果:
- 我们首先定义了一个名为 register 的装饰器函数,将其装饰了 f1() 与 f2() 函数。而这里的 f3() 函数作为比较,没有被装饰;
- 从结果中可以看出执行顺序:装饰器函数比 main 函数还要先执行;
- 加入
__name__ == '__main__'
是为了让该python文件可以当做模块导入到其他文件1。因为 python 文件默认是从上往下执行,导入后,就不会执行到 main() 代码。毕竟导入的目的是为了使用其定义的函数或者类方法。
实际应用过程:
- 一般是定义在一个独立模块中,使用时会被导入到其它模块;
- 函数装饰器会在内部定义一个新函数,然后返回。
- Python中’main’模块的作用.
- Luciano Ramalho (作者),安道,吴珂 (译者).流畅的Python[M].人民邮电出版社,2017:301-305.