Python Decorators
A um bom tempo atrás (dezembro de 2009) escrevi um artigo sobre “decorators” em Python. O texto foi inspirado num post no blog do pessoal da Artima( mais precisamente do Bruce Eckel) que falava sobre o assunto.
De lá para cá, apareceram mais artigos e o uso de decorators ganhou bastante força em bibliotecas, frameworks, etc. Diante disso, e de diversos pedidos que recebo, resolvi re-visitar o assunto.
No wiki do Python, a definição de decorator, é de uma forma que temos para alterar um comportamento de um função ou métodos dentro de um código. Seria como se pudéssemos adicionar ou até alterar a lógica sem sermos muitos intrusivos.
Um bom exemplo seria o decorator classmethod. Veja abaixo:
def metodo1(self):
print "Ola Mundo"
Na classe acima, para usarmos o método “metodo1″, precisamos de uma instância de OlaMundo.
olaMundo.metodo1()
OlaMundo.metodo1(olaMundo)
Para transformar o metodo1 ou escrever um metodo2 que pertença a classe e não a uma instância, você tem que fazer:
def metodo1(self):
print "Ola Mundo"
metodo1 = classmethod(metodo1)
Já o decorator, como uma macro em C, tornar o código mais legível e faz essa “mágica” para a gente:
@classmethod
def metodo1(self):
print "Ola Mundo"
O que são os Decorators e como funciona:
Os decorators do Python são como macros ( já disse isso) que quanto o interpretador os encontra os substitui por um estrutura que foi definida. No caso do classmethod ele “substitui” pela a chamada original.
Claro que a definição acima é simplista, mas ajuda a entender.
Nos aprofundando mais, ele é semelhante ao with do Python. Ele é uma classe que no seu init recebe o objeto a qual foi associado e um método call (ele é um Callable). Esse método call é chamado e ai você pode fazer algo.
def __init__(self, function):
self.f = function
def __call__(self):
print "Ola Mundo"
@MeuDecorador
def funcao():
print "algo assim"
funcao()
O código acima mostra bem (execute-o) como funciona um decorator. No meu caso, eu simplesmente coloquei um print. Mas no método eu posso abrir um conexão, colocar um log, medir tempo, colocar numa, fila, emitir um sinal, adicionar o método como callback numa evento, etc.
Para que servem e por que usar:
Decorators não trazem nenhum grande novidade a linguagem (está desde a versão 2.2 se não me engano), mas alteram e melhoram a sintaxe de nossos códigos facilitando a compreensão do que está acontecendo ali.
Referência.
[1] http://wiki.python.org/moin/PythonDecorators
[2] http://www.tocadoelfo.com.br/2009/10/python-decorators-uma-introducao.html
[3] http://devlog.waltercruz.com/python_decorators
[4] http://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html
[5] http://wiki.python.org/moin/PythonDecoratorLibrary
