(一) 装饰器基础知识
什么是Python装饰器?Python里装饰器是一个可调用的对象(函数),其参数是另一个函数(被装饰的函数)
假如有一个名字为somedecorator的装饰器,target是被装饰的函数:
>>> @somedecorator ... def target(): ... print("running target")
上面代码的效果和下面的书写一样:
>>> target = somedecorator(target)
@somedecorator只是语法糖,工作原来就是上面这句代码,为了确认这个原理,我们看看下面控制台信息:
>>> def somedecorator(func): ... def inner(): ... print("running inner") ... return inner ... >>> @somedecorator ... def target(): ... print("running target") ... >>> target() running inner >>> target <function somedecorator.<locals>.inner at 0x7f20829fb950> >>>
从控制台信息我们可以看到target()语句只输出了somedecorator 里inner()的print,target函数已经被替换为somedocorator的返回值inner函数的引用。
从以上示例我们看到了装饰器第一个特性:能把被装饰的函数替换成其他函数。
下面我们看装饰器的第二个特性:import时执行:
(二)Python何时执行装饰器
我们通过一个示例来看效果:
有如下的py源文件Example7_2.py:
registry = [] def register(func): print("running register(%s)" % func) registry.append(func) return func @register def f1(): print("running f1") @register def f2(): print("running f2") def f3(): print("running f3") def main(): print("running main") print("registry ->", registry) f1() f2() f3() if __name__ == "__main__": main()
register是装饰器,f1和f2被register装饰,f3没有
我们尝试import Example7_2,看看控制台的输出:
>>> import Example7_2 running register(<function f1 at 0x7f9b534926a8>) running register(<function f2 at 0x7f9b53492730>)
从控制台信息我们看到import Example7_2时,@register 就立即执行
我们再运行程序:
# python3 Example7_2.py running register(<function f1 at 0x7fab49f750d0>) running register(<function f2 at 0x7fab49f75158>) running main registry -> [<function f1 at 0x7fab49f750d0>, <function f2 at 0x7fab49f75158>] running f1 running f2 running f3
这里看到被装饰的函数f1,f2在运行时才执行
这就是导入时和运行时的区别,
好了,今天先到这里,再会。