Embora eu goste de me considerar um codificador Python razoavelmente competente, um aspecto da linguagem que nunca consegui entender são os decoradores.
Sei o que são (superficialmente), li tutoriais, exemplos, perguntas sobre o Stack Overflow e entendo a sintaxe, posso escrever minha própria, ocasionalmente use @classmethod e @staticmethod, mas nunca me ocorre usar um decorador para resolver um problema no meu próprio código Python. Nunca encontro um problema em que penso: "Hmm ... isso parece um trabalho para um decorador!"
Então, eu estou querendo saber se vocês podem oferecer alguns exemplos de onde você usou decoradores em seus próprios programas, e espero ter um "A-ha!" momento e obtê- los.
functools.lru_cache
que faz exatamente o que Pedro disse, desde Python 3.2, lançado em fevereiro de 2011.Respostas:
Eu uso decoradores principalmente para fins de tempo
fonte
time.clock()
mede o tempo da CPU. Você pode usartime.time()
se preferir medir o tempo do relógio de parede.myFunction
executar ...Eu os usei para sincronização.
Conforme apontado nos comentários, desde o Python 2.5 você pode usar uma
with
declaração em conjunto com um objetothreading.Lock
(oumultiprocessing.Lock
desde a versão 2.6) para simplificar a implementação do decorador para apenas:Independentemente disso, você o usa assim:
Basicamente, apenas coloca
lock.acquire()
/lock.release()
em ambos os lados da chamada de função.fonte
Uso decoradores para parâmetros de verificação de tipo que são passados para meus métodos Python por meio de alguma RMI. Então, em vez de repetir o mesmo parâmetro de contagem, crie mumbo-jumbo de exceção várias vezes.
Por exemplo, em vez de:
Eu apenas declaro:
e
accepts()
faz todo o trabalho para mim.fonte
@accepts
em PEP 318.isinstance()
função interna, como é feito na implementação do decorador do PEP 318 . Como seuclassinfo
argumento pode ser de um ou mais tipos, usá-lo também mitigaria as objeções (válidas) de @ Gustavo6046. O Python também possui umaNumber
classe base abstrata, portanto testes muito genéricosisinstance(42, numbers.Number)
são possíveis.Os decoradores são usados para qualquer coisa que você queira "envolver" de forma transparente com funcionalidade adicional.
O Django os usa para agrupar a funcionalidade "login required" nas funções de visualização , bem como para registrar funções de filtro .
Você pode usar decoradores de classe para adicionar logs nomeados às classes .
Qualquer funcionalidade suficientemente genérica que você possa "aderir" a uma classe ou comportamento de função existente é um jogo justo para decoração.
Há também uma discussão de casos de uso no grupo de notícias Python-Dev apontado pelo PEP 318 - Decoradores de funções e métodos .
fonte
Para testes nos, você pode escrever um decorador que forneça uma função ou método de teste de unidade com vários conjuntos de parâmetros:
fonte
A biblioteca Twisted usa decoradores combinados com geradores para dar a ilusão de que uma função assíncrona é síncrona. Por exemplo:
Usando isso, o código que teria sido dividido em várias funções de retorno de chamada pode ser escrito naturalmente como um único bloco, facilitando muito o entendimento e a manutenção.
fonte
Um uso óbvio é para o log, é claro:
fonte
Eu os uso principalmente para depuração (wrapper em torno de uma função que imprime seus argumentos e resultado) e verificação (por exemplo, para verificar se um argumento é do tipo correto ou, no caso de aplicativo da Web, se o usuário tem privilégios suficientes para chamar um determinado método).
fonte
Estou usando o decorador a seguir para tornar uma função segura para threads. Isso torna o código mais legível. É quase semelhante ao proposto por John Fouhy, mas a diferença é que se trabalha em uma única função e que não há necessidade de criar explicitamente um objeto de bloqueio.
fonte
Decoradores são usados para definir as propriedades de uma função ou como um padrão que a altera; é possível, mas é contra-intuitivo retornar funções completamente diferentes. Observando as outras respostas aqui, parece que um dos usos mais comuns é limitar o escopo de outro processo - seja log, criação de perfil, verificações de segurança, etc.
CherryPy usa o envio de objetos para corresponder URLs a objetos e, eventualmente, métodos. Decoradores sobre esses métodos sinalizar ou não CherryPy é ainda permitido usar esses métodos. Por exemplo, adaptado do tutorial :
fonte
Eu os usei recentemente, enquanto trabalhava em aplicativos da Web para redes sociais. Para Comunidade / Grupos, eu deveria dar autorização de associação para criar uma nova discussão e responder a uma mensagem de que você precisa ser membro desse grupo específico. Então, eu escrevi um decorador
@membership_required
e coloquei o que eu precisava na minha opinião.fonte
Eu uso esse decorador para corrigir parâmetro
isto escrito quando refatorar algumas funções precisa passar o argumento "wanN", mas nos meus códigos antigos eu passei somente N ou 'N'
fonte
O Decorator pode ser usado para criar facilmente variáveis de método de função.
fonte