Decorador Python com argumentos

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 sayque 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 Himensagem 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 repeatdecorador 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 repeatdecorador.

No entanto, esta solução não é flexível. Por exemplo, você deseja usar o repeatdecorador para executar uma função 5 vezes e outras 10 vezes. O repeatdecorador não atenderia ao requisito.

Para corrigir isso, você precisa alterar o repeatdecorador 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 repeatdecorador, repeat(5)deverá retornar o decorador original.

def repeat(times):
    # return the original "repeat" decorator
Linguagem de código:  Python  ( python )

A nova repeatfunção retorna um decorador. E muitas vezes é chamada de fábrica de decoradores.

A seguinte repeatfunçã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 decoratefunção é um decorador. É equivalente ao repeatdecorador 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.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *