Resumo : neste tutorial, você aprenderá como definir decoradores Python com argumentos usando uma fábrica de decoradores.
Introdução ao decorador Python com argumentos
Suponha que você tenha uma função chamada say
que imprima uma mensagem:
def say(message):
''' print the message
Arguments
message: the message to show
'''
print(message)
Linguagem de código: Python ( python )
e você deseja executar a say()
função 5 vezes repetidamente cada vez que a chamar. Por exemplo:
say('Hi')
Linguagem de código: Python ( python )
Deve mostrar a seguinte Hi
mensagem cinco vezes da seguinte forma:
Hi
Hi
Hi
Hi
Hi
Para fazer isso, você pode usar um decorador comum :
@repeat
def say(message):
''' print the message
Arguments
message: the message to show
'''
print(message)
Linguagem de código: Python ( python )
E você pode definir o repeat
decorador da seguinte forma:
def repeat(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
for _ in range(5):
result = fn(*args, **kwargs)
return result
return wrapper
Linguagem de código: Python ( python )
O seguinte mostra o código completo:
from functools import wraps
def repeat(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
for _ in range(5):
result = fn(*args, **kwargs)
return result
return wrapper
@repeat
def say(message):
''' print the message
Arguments
message: the message to show
'''
print(message)
say('Hello')
Linguagem de código: Python ( python )
E se você quiser executar a say()
função repetidamente dez vezes. Nesse caso, você precisa alterar o valor 5 codificado no repeat
decorador.
No entanto, esta solução não é flexível. Por exemplo, você deseja usar o repeat
decorador para executar uma função 5 vezes e outras 10 vezes. O repeat
decorador não atenderia ao requisito.
Para corrigir isso, você precisa alterar o repeat
decorador para que ele aceite um argumento que especifique o número de vezes que uma função deve ser executada assim:
@repeat(5)
def say(message):
...
Linguagem de código: Python ( python )
Para definir o repeat
decorador, repeat(5)
deverá retornar o decorador original.
def repeat(times):
# return the original "repeat" decorator
Linguagem de código: Python ( python )
A nova repeat
função retorna um decorador. E muitas vezes é chamada de fábrica de decoradores.
A seguinte repeat
função retorna um decorador:
def repeat(times):
''' call a function a number of times '''
def decorate(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
for _ in range(times):
result = fn(*args, **kwargs)
return result
return wrapper
return decorate
Linguagem de código: Python ( python )
Neste código, a decorate
função é um decorador. É equivalente ao repeat
decorador original.
Observe que a nova função de repetição não é um decorador. É uma fábrica de decoradores que devolve decorador.
Junte tudo.
from functools import wraps
def repeat(times):
''' call a function a number of times '''
def decorate(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
for _ in range(times):
result = fn(*args, **kwargs)
return result
return wrapper
return decorate
@repeat(10)
def say(message):
''' print the message
Arguments
message: the message to show
'''
print(message)
say('Hello')
Linguagem de código: Python ( python )
Resumo
- Use um decorador de fábrica para retornar um decorador que aceite argumentos.