#python
Вопрос:
Попробуйте выполнить приведенный ниже код. Почему на выходе выводится только «пропускается» один раз? Мы вызываем rotate_list три раза, и я не понимаю, почему он не запускает весь код внутри __call__()
каждый раз. Я предполагаю, что он печатает его только один раз для создания экземпляра или что-то в этом роде.
class anothercall:
def __init__(self):
self.enabled = True
def __call__(self,f):
print("gets skipped")
def wrap(*args, **kwargs):
if self.enabled:
print('calling {}'.format(f))
return f(*args, **kwargs)
return wrap
another = anothercall()
@another
def rotate_list(l):
return l[1:] [l[0]]
l = [1,2,3]
rotate_list(l)
l = [1,2,3]
rotate_list(l)
l = [1,2,3]
rotate_list(l)
Комментарии:
1. Вы оформили только одну функцию, поэтому декоратор вызывается только один раз.
Ответ №1:
another
вызывается, когда вы определяете rotate_list
, а не когда вы вызываете rotate_list
. Имя rotate_list
-отскок к тому, что another
возвращается.
@another
def rotate_list(l):
...
эквивалентно
def rotate_list(l):
...
rotate_list = another(rotate_list)
Ответ №2:
Когда интерпретатор python сталкивается с функцией с помощью декоратора, он изменяет функцию с помощью функции-оболочки. Для вашей программы rotate_list = another(rotate_list)
это произойдет в строке 14. Это вызов __call__
метода, так что печать «пропускается» один раз.
Затем, когда вы вызываете rotate_list
функцию, это просто вызывающая wrap
функция.