incrível!! Muito bem explicado com uma didatica excepcional! Só que numca entendi muito bem o funcionamento de decorares por esse mesmo motivo não usava, mas agora que entendi o seu real poder vou usar bastante, mas poderia explicar o *args
e o **kwargs
? nunca entendi o significado.
Certamente Tallyson!
Os parâmetros *args
e **kwargs
são antigos companheiros, sendo eles respectivamente uma lista de valores com tamanho variável e um dicionário (chave - valor) de parâmetros.
*args = []
**kwargs = {}
Sendo assim o *args
é utilizado para passar os parâmetros declarados na função.
Exemplo:
# Passando via *args os parâmetros declarados
def exemplo (nome, idade):
print(f'Olá, {nome}, você tem {idade} anos.')
def args (*args):
exemplo(*args)
args('João', 99)
Execução
Olá, João, você tem 99 anos.
Neste exemplo foi passada a quantidade de parâmetros exata, se for passado um número de parâmetros inferior ou superior a quantidade esperada, será gerada uma exceção.
O **kwargs
é utilizado para passar parâmetros adicionais para a função e da mesma forma a função deve ter declarada o parâmetro **kwargs
, para permitir os parâmetros adicionais.
# Passando os parâmetros obrigatórios via *args e mais parâmetros adicionais via **kwargs
def exemplo(nome, idade, **kwargs):
# Imprime todos os parâmetros adicionais
for arg, value in kwargs.items():
print(f'{arg} = {value}')
print(f'Olá, {nome}, você tem {idade} anos.')
def args(*args, **kwargs):
exemplo(*args, **kwargs)
args('João', 99, pai = 'Carlos', mae = 'Joana', tio = 'Pedro')
Execução
pai = Carlos
mae = Joana
tio = Pedro
Olá, João, você tem 99 anos.
Os parâmetros adicionais passados via *kwargs
são muito utilizados para configurar o comportamento do seu método, por exemplo configurar qual formatação utilizar, qual driver utilizar para calcular e etc.
Espero ter ajudado!
Já explicaran o uso dos arga ai
mas um caso de uso interessante que vi no local que trabalho é usar decorators pra implementar retry
A idéia é: caso a função decorada emita um Exception, a mesma será executada mais algumas vezes por meio do controle de um contador recursivo passado como argumento reinjetando.
é curioso
Tipo esse retry ???
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
"""Retry calling the decorated function using an exponential backoff.
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
:param ExceptionToCheck: the exception to check. may be a tuple of
exceptions to check
:type ExceptionToCheck: Exception or tuple
:param tries: number of times to try (not retry) before giving up
:type tries: int
:param delay: initial delay between retries in seconds
:type delay: int
:param backoff: backoff multiplier e.g. value of 2 will double the delay
each retry
:type backoff: int
:param logger: logger to use. If None, print
:type logger: logging.Logger instance
"""
def deco_retry(f):
@wraps(f)
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries > 1:
try:
return f(*args, **kwargs)
except ExceptionToCheck as e:
msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
if logger:
logger.warning(msg)
else:
print(msg)
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
return f(*args, **kwargs)
return f_retry
return deco_retry
Muito bacana essa ideia. Obrigado por compartilhar.
Muito curioso raton!!
Bom saber dessa utilização!