pattern - Usando el decorador de python con o sin paréntesis
python decorator with arguments (2)
Algún código que realmente funciona donde usas el arg dentro del decorador:
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 __name__ == "__main__":
my_func()
my_func1()
El resultado es:
1
aaa
¿Cuál es la diferencia en Python
cuando se usa el mismo decorador con o sin paréntesis ? Por ejemplo:
Sin paréntesis
@someDecorator
def someMethod():
pass
Con paréntesis
@someDecorator()
def someMethod():
pass
someDecorator
en el primer fragmento de código es un decorador regular:
@someDecorator
def someMethod():
pass
es equivalente a
someMethod = someDecorator(someMethod)
Por otro lado, someDecorator
en el segundo fragmento de código es invocable y devuelve un decorador:
@someDecorator()
def someMethod():
pass
es equivalente a
someMethod = someDecorator()(someMethod)
Como señaló Duncan en sus comentarios, algunos decoradores están diseñados para funcionar en ambos sentidos. Aquí hay una implementación bastante básica de dicho decorador:
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
es un ejemplo más complejo.