文章目录
基础知识
定义
装饰器(Decorator)是参数为被装饰函数(function as parameter)的可调用对象(callable object)。
class C:
def meth (cls):
...
meth = classmethod(meth) # Rebind name to wrapped-up class method
通过引入装饰器将上述代码包装为以下形式的等效代码:
class C:
@classmethod
def meth (cls):
...
严格来说,装饰器只是简化编程的语法糖。元编程(运行时改变程序的行为)中常用。
执行时机
装饰器的关键特性之一是其在被装饰的函数定义之后立即运行,即导入时(即Python加载模块时)执行。
# BEGIN REGISTRATION
registry = [] # <1>
def register(func): # <2>
print('running register(%s)' % func) # <3>
registry.append(func) # <4>
return func # <5>
@register # <6>
def f1():
print('running f1()')
@register
def f2():
print('running f2()')
def f3(): # <7>
print('running f3()')
def main(): # <8>
print('running main()')
print('registry ->', registry)
f1()
f2()
f3()
if __name__=='__main__':
main() # <9>
# END REGISTRATION
借助装饰器实现注册功能:
$ python registration.py
running register(<function f1 at 0x000001F67FF974C0>)
running register(<function f2 at 0x000001F67FF97C40>)
running main()
registry -> [<function f1 at 0x000001F67FF974C0>, <function f2 at 0x000001F67FF97C40>]
running f1()
running f2()
running f3()
导入时执行:
>>> import registration
running register(<function f1 at 0x000002E8F38CA160>)
running register(<function f2 at 0x000002E8F38CA0C0>)
使用
装饰器函数与被装饰函数往往不在同一模块中定义。装饰器定义后应用到其他模块中的函数上。
从装饰器的行为上看,装饰器可能会