Metaprogramação em Python

Python é uma linguagem que possui ferramentas bastante poderosas e que, infelizmente, não são muitas pessoas que às utilizam....

Dextra

View posts by Dextra
Somos especialistas em desenvolvimento de software sob medida para negócios digitais. Pioneiros na adoção de metodologias de gestão ágil, combinamos processos de design, UX, novas tecnologias e visão de negócio, desenvolvendo soluções que criam oportunidades para nossos clientes. A Dextra faz parte da Mutant, empresa B2B líder no mercado brasileiro e especialista em Customer Experience para plataformas digitais.
Data de publicação: 09/04/2015

Python é uma linguagem que possui ferramentas bastante poderosas e que, infelizmente, não são muitas pessoas que às utilizam. Uma dessas ferramentas são as metaclasses, que fazem parte de um conceito de metaprogramação juntamente com os decorators. Para começarmos a falar sobre metaclasses, é importante entender alguns comportamentos básicos do Python. Veja só:
[python]
class A(object):
pass
$ print type(A)
>>> <type ‘type’>
$ print type(str)
>>> <type ‘type’>
$ print type([])
>>> <type ‘type’>
[/python]
Até aqui tudo bem: apenas criamos uma classe A (no new-object style), perguntamos qual é o tipo de A e descobrimos que A é do tipo type. Veja que interessante: str e list também são do tipo type. Conclusão: todos os objetos, por padrão, são do tipo type. Agora, veja que se usarmos a função isinstance para verificarmos se A é uma instância de type, descobrimos que isso é verdade. Conclusão 2: Todos os objetos são instâncias de type
[python]
print isinstance(A, A())
>>> True
print isinstance(A, type)
>>> True
[/python]
Logo: A() é uma instância de A, que por sua vez é uma instância de type. É importante entender que type é uma metaclasse; e metaclasses em Python funcionam como fábrica de classes, ou seja, elas criam instâncias de classes. Assim, podemos enriquecer a maneira como trabalhamos criando novas metaclasses. Para isso, basta fazer:
[python]
class MinhaMetaClasse(type): pass
class Usuario():
__metaclass__ = MinhaMetaClasse
[/python]
Essa é a notação para declarar que a minha classe Usuario, terá outra metaclasse como base, que não a type. Ok, até agora ficou claro como funciona o “instanciamento” de classes no Python, mas afinal qual situação eu poderia criar uma nova metaclasse? Alguns exemplos: metaclasse para fazer log de todos os métodos chamados, metaclasse para medir o tempo de execução de todos os métodos da classe que a utiliza, ou impossibilitar a criação de uma instância da classe que usa a metaclasse em questão. O código abaixo implementa  um Logger que fará print toda vez que qualquer método da classe Pessoa for chamado.
[python]
from inspect import disfunction
from date time import date time
def logger_decorator(func):
def log(*args, **kwargs):
print “Funcao %s foi chamada as %s com os parâmetros %s” % (func.__name__, datetime.now(), args)
return func(*args, **kwargs)
return log
class Logger(type):
def __init__(self, namespace, bases, attributes):
for key in attributes:
a_function = attributes[key]
if isfunction(a_function):
new_f = logger_decorator(a_function)
setattr(self, key, new_f) # mesma coisa que instancia.key = new_f
class Pessoa(object):
__metaclass__ = Logger
def ola(self, mensagem):
print mensagem
def sair(self):
print ‘tchau’
p = Pessoa() p.ola(‘blog’)
>>> “Funcao ola foi chamada as 2015-04-02 10:42:54.767371 com os parâmetros (<__main__.Pessoa object at 0x105c31550>, ‘dextra’)”>>> “dextra”
p.sair()
>>> “Funcao sair foi chamada as 2015-04-02 10:42:54.767509 com os parametros (<__main__.Pessoa object at 0x105c31550>,) ”
>>> “tchau”
[/python]
Referências:
Fluent Python (http://shop.oreilly.com/product/0636920032519.do)
Documentação Python (https://docs.python.org/2/reference/datamodel.html?highlight=metaclass#__metaclass__ , https://docs.python.org/3/reference/datamodel.html?highlight=metaclass#customizing-class-creation )

Dextra

View posts by Dextra
Somos especialistas em desenvolvimento de software sob medida para negócios digitais. Pioneiros na adoção de metodologias de gestão ágil, combinamos processos de design, UX, novas tecnologias e visão de negócio, desenvolvendo soluções que criam oportunidades para nossos clientes. A Dextra faz parte da Mutant, empresa B2B líder no mercado brasileiro e especialista em Customer Experience para plataformas digitais.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

oito + 2 =

Posts relacionados

  1. Sobre a Dextra

    Somos especialistas em desenvolvimento de software sob medida para negócios digitais. Pioneiros na adoção de metodologias de gestão ágil, combinamos processos de design, UX, novas tecnologias e visão de negócio, desenvolvendo soluções que criam oportunidades para nossos clientes.

  2. Categorias

Scroll to top