Python 函数装饰器和闭包(装饰器基础知识)
本章内容:
Python 如何计算装饰器句法
Python 如何判断变量是不是局部的
闭包存在的原因和工作原理
nonlocal 能解决什么问题
掌握这些基础知识后,我们可以进一步探讨装饰器:
实现行为良好的装饰器
标准库中有用的装饰器
实现一个参数化装饰器
装饰器基础知识
装饰器是可调用的对象,其参数是另一个函数(被装饰的函数)。 装
饰器可能会处理被装饰的函数,然后把它返回,或者将其替换成另一个
函数或可调用对象。
假如有个名为 decorate 的装饰器:
@decorate
def target():print('running target()')
上述代码的效果与下述写法一样:
def target():print('running target()')
target = decorate(target)
两种写法的最终结果一样:上述两个代码片段执行完毕后得到的
target 不一定是原来那个 target 函数,而是 decorate(target) 返
回的函数。
为了确认被装饰的函数会被替换,请看示例 7-1 中的控制台会话。
示例 7-1 装饰器通常把函数替换成另一个函数
def deco(func):def inner():print('running inner()')return inner() ➊@deco
def target():➋print('running target')>>> target() ➌
running inner()
>>> target ➍
<function deco.<locals>.inner at 0x10063b598>
❶ deco 返回 inner 函数对象。
❷ 使用 deco 装饰 target。
❸ 调用被装饰的 target 其实会运行 inner。
❹ 审查对象,发现 target 现在是 inner 的引用。
严格来说,装饰器只是语法糖。如前所示,装饰器可以像常规的可调用
对象那样调用,其参数是另一个函数。有时,这样做更方便,尤其是做
元编程(在运行时改变程序的行为)时。
综上,装饰器的一大特性是,能把被装饰的函数替换成其他函数。第二
个特性是,装饰器在加载模块时立即执行。