Декоратор - это любое выражение после @
. В первом случае это экземпляр Printer
, поэтому то, что происходит (в значительной степени) эквивалентно
decorator = Printer(1) # an instance of Printer, the "1" is given to __init__
def f():
print 3
f = decorator(f) # == dec.__call__(f) , so in the end f is "wrapped"
Во втором случае это класс Printer, поэтому у вас есть
decorator = Printer # the class
def a():
print 3
a = decorator(a) # == Printer(a), so a is an instance of Printer
Итак, хотя это работает (потому что конструктор Printer
принимает один дополнительный аргумент, как и __call__
), это совершенно другая вещь.
Способ предотвращения этого на python обычно таков: не делайте этого. Уточните (например, в строке документации), как работает декоратор, и затем поверьте, что люди поступают правильно.
Если вы действительно хотите чек, Ответ Eevee предоставляет способ уловить эту ошибку (конечно, во время выполнения - это Python).