我有下面的装饰演示代码。如果我在没有显式调用greet
函数的情况下执行它,它就会在decorator函数中执行print
语句并输出Inside decorator
。
我无法理解装饰器的这种行为。即使我没有调用time_decorator
函数,如何调用greet
?
我使用的是Python 3。
def time_decorator(original_func):
print('Inside decorator')
def wrapper(*args, **kwargs):
start = time.clock()
result = original_func(*args, **kwargs)
end = time.clock()
print('{0} is executed in {1}'.format(original_func.__name__, end-start))
return result
return wrapper
@time_decorator
def greet(name):
return 'Hello {0}'.format(name)
答案 0 :(得分:4)
time_decorator
。 wrapper
不是(这是在调用装饰greet()
时调用的函数)。
@
只是语法糖。以下代码段相同。
装饰器语法:
@time_decorator
def greet(name):
return 'Hello {0}'.format(name)
显式装饰过程 - 装饰器是一个基于另一个返回新功能的函数。
def greet(name):
return 'Hello {0}'.format(name)
greet = time_decorator(greet)
答案 1 :(得分:2)
装饰器在开始时间(当python解释器在程序启动时读取代码时)调用,而不是在运行时 (当实际调用修饰函数时)。
在运行时,它是被调用的包装函数wrapper
,它本身调用修饰函数并返回其结果。
因此执行print
行是完全正常的。
如果,即装饰10个功能,您将看到10倍的打印输出。甚至不需要调用装饰函数来实现这一点。
将print
移到wrapper
内,这不再发生。
Decorators
以及metaclasses
是所谓元编程 (修改/创建代码,来自现有代码)的一部分。这是一个非常迷人的编程方面,需要时间来理解,但提供了惊人的可能性。