预备知识:
我们都知道,python中一切皆对象。也就是说我们的函数也是对象。因此我们能够把函数对象赋值给变量。通过变量来调用函数。如下:
def hello_world():
print("Hello, nice world!")
a = hello_world
a()
上述程序执行的结果为:
Hello, nice world!
为什么需要装饰器
接下来我们来介绍下为什么需要装饰器。不知道大家有没有这样的一个经历。比如在程序调试时,我们可能想要在一些函数中打印一些信息。比如每个函数开始和结束都打印一句,已锁定程序执行顺序等等。比如现在,我有一个say_hello的函数,如下:
def say_hello():
print("Hi, I want to say hello to this world!")
现在我想在它执行前后分别加上“say_hello is start running...“和”say_hello has already done.”两句话。那么你也许会添加如下的代码:
def say_hello():
print("say_hello is start running...")
print("Hi, I want to say hello to this world!")
print("say_hello has already done.")
当然,如果我们只有这一个简单的方式,添加这两句再在测试结束后删除这两句并不是什么大的工作量。但是如果我们想跟踪上百个这样的函数呢?装饰器就是为了解决这种情况而诞生的。装饰器其实就是一个函数,只不过用一种特殊的方式“@”的形式来表示调用过程。如上函数可以改成装饰器版本:
def decorator(func):
def pack(*arg, **kw):
print("{0} is start running...".format(func.__name__))
func(*arg, **kw)
print("{} has already done.".format(func.__name__))
return pack
@decorator
def say_hello():
print("Hi, I want to say hello to this world!")
say_hello()
以上的输出是:
say_hello is start running...
Hi, I want to say hello to this world!
say_hello has already done.
其实上面的@decorator就是相当于decorator(say_hello)。这像是用decorator函数对say_hello进行了包装修饰。这也许就是装饰器名字的来源。
网友评论