Выполнение функции декоратора Python
У меня есть демонстрационный код декоратора. Если я выполняю его без явного вызова функции greet
, он выполняет инструкцию 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)
Ответы
Ответ 1
Декораторы вызывают время старт (когда интерпретатор python считывает код при запуске программы), а не время выполнения (когда фактически декорированная функция).
Во время выполнения это вызываемая функция wrapper
, которая сама вызывает украшенную функцию и возвращает ее результат.
Итак, это абсолютно нормально, что выполняется строка print
.
Если вы украшаете 10 функций, вы увидите в 10 раз больше результатов печати. Не нужно даже вызывать украшенные функции для этого.
Переместите print
внутри wrapper
, и этого больше не будет.
Decorators
, а также metaclasses
являются частью того, что называется мета-программированием (изменить/создать код из существующего кода). Это действительно увлекательный аспект программирования, который требует времени, чтобы понять, но предлагает потрясающие возможности.
Ответ 2
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)