Не думаю, что вы понимаете декораторов.Давайте сделаем минимальный пример.
def my_decorator(some_function):
def new_function(*args, **kwargs):
'announces the result of some_function, returns None'
result = some_function(*args, **kwargs)
print('{} produced {}'.format(some_function.__name__, result))
return new_function # NO FUNCTION CALL HERE!
@my_decorator
def my_function(a, b):
return a + b
my_function(1, 2) # will print "my_function produced 3"
У нас есть простая функция my_function
, которая возвращает сумму двух своих аргументов, и декоратор, который просто распечатает результат любой функции, которую он украшает.
Обратите внимание, что
@my_decorator
def my_function(a, b):
return a + b
эквивалентно
def my_function(a, b):
return a + b
my_function = my_decorator(my_function)
Поскольку my_decorator
принимает функцию в качестве аргумента (здесь мы даем ее my_function
) и возвращает новая функция new_function
(без вызова!), Мы фактически переопределяем my_function
, потому что мы переназначаем имя на то, что возвращает my_decorator
.
В действии:
>>> my_function(1, 2)
my_function produced 3
Обратите внимание, что в каждой точке примера, когда вызывается функция, это происходит с синтаксисом в скобках.Вот все вызовы функций, которые происходят в первом блоке кода, который я разместил, в следующем порядке:
my_decorator(my_function)
вызывается и возвращаемое значение переназначается на имя my_function
.Это происходит либо через синтаксис @
, либо более явно в эквивалентном фрагменте кода. Вызывается my_function(1, 2)
.На этом этапе my_function
- это new_function
, полученный декоратором.Проанализируйте его как new_function(1, 2)
. - Внутри тела
new_function
аргумент, который мы дали my_decorator
, называется (result = some_function(*args, **kwargs)
), что является значением my_function
до переназначения, которое произошло в шаге 1 . print
.
Если вы хотите понять, как new_function
удерживает some_function
несмотря на то, что my_decorator
уже вернулся с вызова, я предлагаю изучить темы свободные переменные и замыкания .