Quelle est la différence dans Python
lorsque vous utilisez le même décorateur avec ou sans parenthèses ? Par exemple:
Sans parenthèses
@someDecorator
def someMethod():
pass
Avec des parenthèses
@someDecorator()
def someMethod():
pass
someDecorator
dans le premier extrait de code est un décorateur régulier:
@someDecorator
def someMethod():
pass
est équivalent à
someMethod = someDecorator(someMethod)
Par ailleurs, someDecorator
dans le deuxième extrait de code est un appelable qui renvoie un décorateur:
@someDecorator()
def someMethod():
pass
est équivalent à
someMethod = someDecorator()(someMethod)
Comme l'a souligné Duncan dans ses commentaires, certains décorateurs sont conçus pour fonctionner dans les deux sens. Voici une jolie implémentation de base d'un tel décorateur:
def someDecorator(arg=None):
def decorator(func):
def wrapper(*a, **ka):
return func(*a, **ka)
return wrapper
if callable(arg):
return decorator(arg) # return 'wrapper'
else:
return decorator # ... or 'decorator'
pytest.fixture
est un exemple plus complexe.
Certains codes fonctionnant réellement où vous utilisez le décorateur arg inside:
def someDecorator(arg=None):
def decorator(func):
def wrapper(*a, **ka):
if not callable(arg):
print (arg)
return func(*a, **ka)
else:
return 'xxxxx'
return wrapper
if callable(arg):
return decorator(arg) # return 'wrapper'
else:
return decorator # ... or 'decorator'
@someDecorator(arg=1)
def my_func():
print('aaa')
@someDecorator
def my_func1():
print('bbb')
if __== "__main__":
my_func()
my_func1()
La sortie est:
1
aaa