Декоратор - это функция, которой на вход подаётся функция и вернуть он должен тоже функцию. Например:
@decorator
def foo():
..
Эквивалентно
foo = decorator(foo)
Теперь про случай из вопроса. В качестве декоратора вместо обычной функции вы используете класс (точнее его объект):
@FuncDec()
def foo():
print('Hello')
Эквивалентно
foo = FuncDec()(foo)
, а именно:
- создаётся объект
FuncDec
(вызывается конструктор __init__
)
- этот объект вызывается (
__call__
) вместе с параметром foo
- объект вернул функцию
wrapper
, которая и будет в дальнейшем выполняться вместо объявленной foo
- профит
Но если убрать скобки, то получится эквивалент
foo = FuncDec(foo)
То есть просто вызов конструктора, который у вас не принимает параметров - поэтому и ругается.