分类目录:《系统学习Python》总目录


函数装饰器已经从Python2.4开始可用。正如我们在前文所见到的,它们大体上是一种语法糖:在def语句结束时通过另一个函数来运行这个函数,把最初的函数名重新绑定到返回的结果。

函数装饰器是一种关于函数的运行时声明,函数的定义需要遵守此声明。装饰器在定义函数或方法的def语句的前一行编写,并且它由@符号以及紧随其后的对于元函数的一个引用组成.这是管理另一个函数的函数(或其他的可调用对象)。

从编写角度看,函数装饰器自动映射如下的语法:

@decorator
def F(arg):
    pass

F(x)

上述代码为接下来代码的等同形式,其中decorator是一个单参数的可调用对象,它返回与F具有相同数目参数的一个可调用对象(而不是映射为F自身):

def F(arg):
    pass

F = decorator(F)

F(x)

这一自动名称重绑定在def语句上有效,不管它针对一个简单的数或是类中的一个方法。当随后调用F函数的时候,它自动调用装饰器所返回的对象,该对象可能是实现了所需的包装逻辑的另一个对象,或者是最初的函数本身。

换句话说,装饰实际把如下的第一行映射为第二行一一尽管装饰器实际上只在装饰的时候运行一次:

func(x)
decorator(func)(x)

这一自动名称重绑定说明了我们在之前文章中遇到的静态方法和property装饰语法的原因:

class A():
    @staticmethod
    def a():     # a = staticmethod(a)
        pass

class B():
    @property
    def b():     # b = property(b)
        pass

在上述两个例子中,在def语句的末尾,方法名重新绑定到一个内置函数装饰器的返回结果。随后再调用最初的名称,将会调用装饰器所返回的对象。在这些特定的情形下,原始的名称被重绑定到一个静态方法路由器和property描述符,但是其过程要更加通用。

参考文献:
[1] Mark Lutz. Python学习手册[M]. 机械工业出版社, 2018.