SlideShare a Scribd company logo
1 of 38
Metaprogramação em Python



    Para ajudar em nosso dia a dia




                   
Metaprogramação


    Programação:
    Dados → Código → Dados

    Metaprogramação:
    Programa → Código → Programa



                   
Metaprogramação


    ● Refletir
    ● Alterar


    ● Estender




                  
Metaprogramação em python

    ●   Tudo é objeto, tudo é atribuível
    ●   Method missing
    ●   Metaclasses
    ●   Builtins types




                               
Classe tradicional

    class Pessoa(object):

      def __init__(self, nome):
        self.nome = nome

      def andar(self, metros):
        print "%s andou %d metros" % 
             (self.nome, metros)

    eu = Pessoa("Tiago")
    eu.andar(10)

                              
Outra maneira de criar

    def construtor(self, nome):
      self.nome = nome

    def andar(self, metros):
      print "%s andou %d metros" %
      (self.nome, metros)

    Pessoa = type("Pessoa", (object,), {
       "__init__": construtor,
       "andar": andar
    })

                              
Reflexão

    print eu.__class__
    > <class '__main__.Pessoa'>
    print Pessoa.__class__
    > <type 'type'>
    print Pessoa.__bases__
    > (<type 'object'>,)
    print Pessoa.__dict__
    > {'andar': <function andar at 0x7f27b159e230>, … }
    print eu.__dict__
    > {'nome': 'Tiago'}


                             
Métodos na classe

    def cantar(self, musica):
      print u"%s cantou ♪ %s ♪" % 
              (self.nome, musica)
    Pessoa.cantar = cantar

    eu = Pessoa("Tiago")
    eu.cantar("Pra Sonhar")
    > Tiago cantou ♪ Pra Sonhar ♪

    ela = Pessoa("Zilah")
    ela.cantar("Felicidade")
 
    > Zilah cantou ♪ Felicidade ♪
                            
Métodos na instância

    def cantar(self, musica):
      print u"%s cantou ♪ %s ♪" % 
              (self.nome, musica)

    from types import MethodType
    eu.cantar = MethodType(cantar, eu)
    eu.cantar("Pra Sonhar")
    > Tiago cantou ♪ Pra Sonhar ♪

    ela.cantar("Felicidade")
    > AttributeError: 'Pessoa' object has no
 
      attribute 'cantar'    
Adicionando superclasses

    class CantorMixin():
       def cantar(self, musica):
         print u"%s cantou ♪ %s ♪" % (self.nome, musica)

    eu = Pessoa("Tiago")
    Pessoa.__bases__ += (CantorMixin,)
    eu.cantar("Pra Sonhar")




                             
Qual utilidade?



        Alguns exemplos




                
1- Stub para teste

class TestUser(TestCase):

     def test_friends_names(self):
       friends = [{'name': 'Bruno'},{'name':'Renan'}]
       Facebook.get_friends = lambda obj: friends
       returned = User().friends_names()
       assert returned == ['Bruno','Renan']

     def setUp(self):
       self.__get_friends = Facebook.get_friends

     def tearDown(self):
       Facebook.get_friends = self.__get_friends
                                  
2- Estender frameworks

class ExtendedFindersMixin():
   def cached(self):
     #...
   def paged(self, page=None, size=None):
     #...

Manager.__bases__ += (ExtendedFindersMixin, )
QuerySet.__bases__ += (ExtendedFindersMixin, )

#Usando:
User.objects.filter(age__gte=18).paged(1,10).cached()


                             
3- NullObjects sem Factory

class UserQuiz(object):

     def __init__(self, id):
       if not id:
           self.null_object()

     def null_object(self):
       self.answer = MethodType(lambda a: False, self)
       self.answer_list = MethodType(lambda a: [], self)

     def answer(self): #...
     def answer_list(self): #...

                                    
Metaprogramação em python

    ●   Tudo é objeto, tudo é atribuível
    ●   Method missing
    ●   Metaclasses
    ●   Builtins types




                               
Attribute missing
class Pessoa(object):

     def __init__(self, nome):
       self.nome = nome

     def __getattr__(self, attr):
       return "%s nao possui o atributo %s"
              % (self.nome, attr)

eu = Pessoa("Tiago")
print eu.nome → Tiago
print eu.idade → Tiago nao possui o atributo idade

                                  
Method missing
class Pessoa(object):

     def __getattr__(self, attr):
       def tentar(*args):
          print "%s tentou %s (%s)" % (self.nome, attr, args)
       return tentar

     def andar(self, metros):
       print "%s andou %s metros" % (self.nome, metros)

eu = Pessoa("Tiago")
eu.andar(10) →Tiago andou 10 metros
eu.falar("Blablabla") →Tiago tentou falar (('Blablabla',))
                                 
Operadores

class Pessoa(object):
   def multiplicar(self, v):
     return [ Pessoa(self.nome) for i in range(v) ]
   def soma(self, v):
     return Pessoa(self.nome[0:3]+v.nome[0:3])

     __mul__ = multiplicar
     __add__ = soma

print Pessoa("Smith") * 3 → ['Smith', 'Smith', 'Smith']
print (Pessoa("Tiago") + Pessoa("Zilah")).nome → "TiaZil”


                                
Qual utilidade?



        Alguns exemplos




                
Lazy load
class SemanticEntity(object):

     def __init__(self, uri):
       self.uri = uri
       self.attrs = None

     def __getattr__(self, attr):
       self.__lazy_load()
       val = self.attrs.get(attr)
       if self.__is_entity(val):
           return self.__class__(val)
       return val

     def __lazy_load(self):
       if self.attrs is None:
          self.__load()
                                         
Lazy load

eu = SemanticEntity("http://globo.com/tiago”)

print eu.nome → Tiago
print eu.apaixonado_por.nome → Zilah
print eu.apaixonado_por.uri → http://globo.com/zilah
print eu.apaixonado_por.apaixonado_por.nome → Tiago




                              
Conquistar uma namorada

    class Pessoa(object):

      def coracao(self, v):
        if v == 3:
           return "Zilah"

      __lt__ = coracao

    tiago = Pessoa()
    print tiago <3


                               
Metaprogramação em python

    ●   Tudo é objeto, tudo é atribuível
    ●   Method missing
    ●   Metaclasses
    ●   Builtins types




                               
O que é?


    Classe:
    → Fábica de instâncias

    Metaclasse:
    → Fábrica de classes



                      
Metaclasse... chata

class MetaClasseChata(type):

    def __new__(cls, name, bases, dct):
      print "Alocando memoria para %s" % name
      return type.__new__(cls, name, bases, dct)

    def __init__(cls, name, bases, dct):
      print "Criando classe %s" % name
      super(MetaClasseChata, cls).__init__(name,bases,dct)

    def metodo_da_classe(cls):
      print "Metodo da classe"

                              
Metaclasse... chata

class ClasseChata(object):
   __metaclass__ = MetaClasseChata

print ClasseChata.metodo_da_classe()
print type(ClasseChata)

----------------------------------------------------

Alocando memoria para ClasseChata
Criando classe ClasseChata
Metodo da classe
<class '__main__.MetaClasseChata'>

                                        
Um exemplo legal



               Selfless python
    Por João Sebastião de Oliveira Bueno
       http://metapython.blogspot.com




                       
Mas antes: Descriptors

    from random import random

    class NumeroAleatorioDescriptor(object):
       def __get__(self, instance, classe):
         return int(random()*100)

    class Roleta(object):
       valor = NumeroAleatorioDescriptor()

    print Roleta().valor


                                
Selfless python
class SelflessDescriptor(object):
   def __init__(self, func):
     self.func = func
   def __get__(self, instance, class_):
     new_globals = self.func.func_globals.copy()
     new_globals["self"] = instance
     new_func = FunctionType(self.func.func_code,
         new_globals, self.func.func_name,
         self.func.func_defaults,
         self.func.func_closure)
     return new_func

class Selfless(type):
   def __new__(cls, name, bases, dict_):
     for key, val in dict_.items():
        if isinstance(val, FunctionType):
            dict_[key] = SelflessDescriptor(val)
 
     return type(name, bases, dict_)  
Selfless python

    __metaclass__ = Selfless

    class A:
       def __init__(a, b):
         self.a = a
         self.b = b




                                
Metaprogramação em python

    ●   Tudo é objeto, tudo é atribuível
    ●   Method missing
    ●   Metaclasses
    ●   Builtins types




                               
Fuuuuuuuu

from datetime import datetime
datetime.now = lambda: None
TypeError: can't set attributes of built-in/extension
           type 'datetime.datetime'

set.get = lambda: None
TypeError: can't set attributes of built-in/extension type 'set'

list.index = lambda i: None
TypeError: can't set attributes of built-in/extension type 'list'

str.split = lambda: None
TypeError: can't set attributes of built-in/extension type 'str'

                                   
Datetime: Jeitinho brasileiro
import datetime as dt_module
from datetime import datetime

class TestArtist(TestCase):
   def test_should_find_news_by_date(self):
     today = datetime.today()
     dt_module.datetime = DateTimeFake(today)

    def get_by_date_fake(obj, date):
      self.used_date = date
      return []
    NewsRepository.get_by_date = get_by_date_fake

    Artist().news()
    assert self.used_date == today
                                 
O jeito é uma herancinha
com você
class BetterDict(dict):

    def __getattr__(self, attr):
      return self.__getitem__(attr)

    def __setattr__(self, attr, val):
      self.__setitem__(attr, val)

x = BetterDict({'a': 'A'})
x['b'] = 'B'
x.c = 'C'

print x.a, x.b, x.c → A B C
print x['a'], x['b'], x['c'] → A B C
                                        
O jeito é uma herancinha
com você
class BetterList(list):

    def subtraction(self, other):
      for i in other:
         if i in self:
             self.remove(i)
      return self

    __isub__ = subtraction


x = BetterList([1,2,3,4])
x -= [2, 4]
print x → [1, 3]
                                     
Outras coisas legais...

        … mas que não são metaprogramação

    ●   Decorators
    ●   With Statement
    ●   Multiprocessing




                           
Conclusão

    ●   Ruby
    ●   Python
    ●   Java




                  
Mantenha contato

timotta@gmail.com

@timotta

http://programandosemcafeina.blogspot.com




                      

More Related Content

What's hot

Ne aula 4. suplementação
Ne   aula 4. suplementaçãoNe   aula 4. suplementação
Ne aula 4. suplementaçãoEric Liberato
 
Fichas tecnicas promimp
Fichas tecnicas promimpFichas tecnicas promimp
Fichas tecnicas promimpIrene Carvalho
 
Nh aula 1 - intro, tmb, dr is
Nh   aula 1 - intro, tmb, dr isNh   aula 1 - intro, tmb, dr is
Nh aula 1 - intro, tmb, dr isEric Liberato
 
MEDIDAS E AVALIAÇÃO ANTROPOMETRIA
MEDIDAS E AVALIAÇÃO ANTROPOMETRIAMEDIDAS E AVALIAÇÃO ANTROPOMETRIA
MEDIDAS E AVALIAÇÃO ANTROPOMETRIAgodesimoes
 
Dietética e confecção de alimentos
Dietética e confecção de alimentosDietética e confecção de alimentos
Dietética e confecção de alimentosPaulo Vaz
 
Alimentação saudável e equilibrada
Alimentação saudável e equilibradaAlimentação saudável e equilibrada
Alimentação saudável e equilibradaCatalin Danu
 
Nutrição - Pirâmide Alimentar
Nutrição - Pirâmide AlimentarNutrição - Pirâmide Alimentar
Nutrição - Pirâmide AlimentarFernanda Clara
 
10 mandamentos - VIDA SAUDAVEL
10 mandamentos - VIDA SAUDAVEL10 mandamentos - VIDA SAUDAVEL
10 mandamentos - VIDA SAUDAVELGraca Miguel
 
Declaração de autorização
Declaração de autorizaçãoDeclaração de autorização
Declaração de autorizaçãoRafael Vinícius
 
Alimentação e qualidade de vida
Alimentação e qualidade de vidaAlimentação e qualidade de vida
Alimentação e qualidade de vidaphtizzo
 

What's hot (20)

Dietoterapia doenças gastro intestinais
Dietoterapia doenças gastro intestinaisDietoterapia doenças gastro intestinais
Dietoterapia doenças gastro intestinais
 
Apresentação dieta e nutrição
Apresentação dieta e nutriçãoApresentação dieta e nutrição
Apresentação dieta e nutrição
 
Declaração de rendimentos
Declaração de rendimentosDeclaração de rendimentos
Declaração de rendimentos
 
Nutrição esportiva e suplementação FV
Nutrição esportiva e suplementação FVNutrição esportiva e suplementação FV
Nutrição esportiva e suplementação FV
 
Emagrecimento
EmagrecimentoEmagrecimento
Emagrecimento
 
Fagioli
FagioliFagioli
Fagioli
 
Ne aula 4. suplementação
Ne   aula 4. suplementaçãoNe   aula 4. suplementação
Ne aula 4. suplementação
 
Fichas tecnicas promimp
Fichas tecnicas promimpFichas tecnicas promimp
Fichas tecnicas promimp
 
Exercicio, nutrição e emagrecimento 01
Exercicio, nutrição e emagrecimento 01Exercicio, nutrição e emagrecimento 01
Exercicio, nutrição e emagrecimento 01
 
Nh aula 1 - intro, tmb, dr is
Nh   aula 1 - intro, tmb, dr isNh   aula 1 - intro, tmb, dr is
Nh aula 1 - intro, tmb, dr is
 
NUTRIÇÃO NO IDOSO
NUTRIÇÃO NO IDOSONUTRIÇÃO NO IDOSO
NUTRIÇÃO NO IDOSO
 
MEDIDAS E AVALIAÇÃO ANTROPOMETRIA
MEDIDAS E AVALIAÇÃO ANTROPOMETRIAMEDIDAS E AVALIAÇÃO ANTROPOMETRIA
MEDIDAS E AVALIAÇÃO ANTROPOMETRIA
 
Dietética e confecção de alimentos
Dietética e confecção de alimentosDietética e confecção de alimentos
Dietética e confecção de alimentos
 
Teste de aceitabilidade orientações
Teste de aceitabilidade orientaçõesTeste de aceitabilidade orientações
Teste de aceitabilidade orientações
 
Macronutrientes
MacronutrientesMacronutrientes
Macronutrientes
 
Alimentação saudável e equilibrada
Alimentação saudável e equilibradaAlimentação saudável e equilibrada
Alimentação saudável e equilibrada
 
Nutrição - Pirâmide Alimentar
Nutrição - Pirâmide AlimentarNutrição - Pirâmide Alimentar
Nutrição - Pirâmide Alimentar
 
10 mandamentos - VIDA SAUDAVEL
10 mandamentos - VIDA SAUDAVEL10 mandamentos - VIDA SAUDAVEL
10 mandamentos - VIDA SAUDAVEL
 
Declaração de autorização
Declaração de autorizaçãoDeclaração de autorização
Declaração de autorização
 
Alimentação e qualidade de vida
Alimentação e qualidade de vidaAlimentação e qualidade de vida
Alimentação e qualidade de vida
 

Similar to Meta-programacao em python

Introdução à Linguagem de programação Python
Introdução à Linguagem de programação PythonIntrodução à Linguagem de programação Python
Introdução à Linguagem de programação Pythondmmartins
 
Programando em python classes
Programando em python   classesProgramando em python   classes
Programando em python classessamuelthiago
 
Palestra python
Palestra pythonPalestra python
Palestra pythonRony Cruch
 
Python: Iteraveis, geradores etc
Python: Iteraveis, geradores etcPython: Iteraveis, geradores etc
Python: Iteraveis, geradores etcLuciano Ramalho
 
Design de código: princípios e práticas para ter um código sustentável
Design de código: princípios e práticas para ter um código sustentávelDesign de código: princípios e práticas para ter um código sustentável
Design de código: princípios e práticas para ter um código sustentávelAndrews Medina
 
Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Luciano Ramalho
 
Encapsulamento com descritores
Encapsulamento com descritoresEncapsulamento com descritores
Encapsulamento com descritoresLuciano Ramalho
 
Encapsulamento com Descritores em Python
Encapsulamento com Descritores em PythonEncapsulamento com Descritores em Python
Encapsulamento com Descritores em PythonLuciano Ramalho
 
POO-FundamentosPOO.pdf
POO-FundamentosPOO.pdfPOO-FundamentosPOO.pdf
POO-FundamentosPOO.pdfFausto Ayres
 
Grails - Destaques (para quem já sabe Java)
Grails - Destaques (para quem já sabe Java)Grails - Destaques (para quem já sabe Java)
Grails - Destaques (para quem já sabe Java)Douglas Mendes
 
Aula 3 - Java Prof.ª Cristiane Fidelix
Aula 3 -  Java Prof.ª Cristiane FidelixAula 3 -  Java Prof.ª Cristiane Fidelix
Aula 3 - Java Prof.ª Cristiane FidelixCris Fidelix
 
Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)Luciano Ramalho
 

Similar to Meta-programacao em python (20)

Introdução à Linguagem de programação Python
Introdução à Linguagem de programação PythonIntrodução à Linguagem de programação Python
Introdução à Linguagem de programação Python
 
Programando em python classes
Programando em python   classesProgramando em python   classes
Programando em python classes
 
Palestra python
Palestra pythonPalestra python
Palestra python
 
Python: Iteraveis, geradores etc
Python: Iteraveis, geradores etcPython: Iteraveis, geradores etc
Python: Iteraveis, geradores etc
 
Programando em python - Classes
Programando em python -  ClassesProgramando em python -  Classes
Programando em python - Classes
 
Design de código: princípios e práticas para ter um código sustentável
Design de código: princípios e práticas para ter um código sustentávelDesign de código: princípios e práticas para ter um código sustentável
Design de código: princípios e práticas para ter um código sustentável
 
Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011
 
Encapsulamento com descritores
Encapsulamento com descritoresEncapsulamento com descritores
Encapsulamento com descritores
 
Encapsulamento com Descritores em Python
Encapsulamento com Descritores em PythonEncapsulamento com Descritores em Python
Encapsulamento com Descritores em Python
 
Metaprogramming
Metaprogramming Metaprogramming
Metaprogramming
 
Código Limpo
Código LimpoCódigo Limpo
Código Limpo
 
Python 02
Python 02Python 02
Python 02
 
POO-FundamentosPOO.pdf
POO-FundamentosPOO.pdfPOO-FundamentosPOO.pdf
POO-FundamentosPOO.pdf
 
Workshop Django
Workshop DjangoWorkshop Django
Workshop Django
 
Grails - Destaques (para quem já sabe Java)
Grails - Destaques (para quem já sabe Java)Grails - Destaques (para quem já sabe Java)
Grails - Destaques (para quem já sabe Java)
 
Aula5
Aula5Aula5
Aula5
 
(2014-04-16) [Garoa HC] Strategy
(2014-04-16) [Garoa HC] Strategy(2014-04-16) [Garoa HC] Strategy
(2014-04-16) [Garoa HC] Strategy
 
Prog web 06-php-oo
Prog web 06-php-ooProg web 06-php-oo
Prog web 06-php-oo
 
Aula 3 - Java Prof.ª Cristiane Fidelix
Aula 3 -  Java Prof.ª Cristiane FidelixAula 3 -  Java Prof.ª Cristiane Fidelix
Aula 3 - Java Prof.ª Cristiane Fidelix
 
Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)
 

More from Tiago Albineli Motta

Challenges and research for a real-time recommendation at OLX
Challenges and research for a real-time recommendation at OLXChallenges and research for a real-time recommendation at OLX
Challenges and research for a real-time recommendation at OLXTiago Albineli Motta
 
Inteligência Artificial: Da ciência da computação à ciência de dados
Inteligência Artificial: Da ciência da computação à ciência de dadosInteligência Artificial: Da ciência da computação à ciência de dados
Inteligência Artificial: Da ciência da computação à ciência de dadosTiago Albineli Motta
 
Machine Learning no dia a dia do desenvolvedor (Atualizado)
Machine Learning no dia a dia do desenvolvedor (Atualizado)Machine Learning no dia a dia do desenvolvedor (Atualizado)
Machine Learning no dia a dia do desenvolvedor (Atualizado)Tiago Albineli Motta
 
Machine Learning no dia a dia do desenvolvedor
Machine Learning no dia a dia do desenvolvedorMachine Learning no dia a dia do desenvolvedor
Machine Learning no dia a dia do desenvolvedorTiago Albineli Motta
 
Machine Learning e experimentos online para evitar o cancelamento no GloboPlay
Machine Learning e experimentos online para evitar o cancelamento no GloboPlayMachine Learning e experimentos online para evitar o cancelamento no GloboPlay
Machine Learning e experimentos online para evitar o cancelamento no GloboPlayTiago Albineli Motta
 
A ciência de dados por traz de sistemas de recomendação
A ciência de dados por traz de sistemas de recomendaçãoA ciência de dados por traz de sistemas de recomendação
A ciência de dados por traz de sistemas de recomendaçãoTiago Albineli Motta
 
Recomendação de ponta a ponta na Globo.com
Recomendação de ponta a ponta na Globo.comRecomendação de ponta a ponta na Globo.com
Recomendação de ponta a ponta na Globo.comTiago Albineli Motta
 
Testes unitários e de integração: Quando e Porque
Testes unitários e de integração: Quando e PorqueTestes unitários e de integração: Quando e Porque
Testes unitários e de integração: Quando e PorqueTiago Albineli Motta
 

More from Tiago Albineli Motta (18)

Multi Armed Bandit
Multi Armed BanditMulti Armed Bandit
Multi Armed Bandit
 
Challenges and research for a real-time recommendation at OLX
Challenges and research for a real-time recommendation at OLXChallenges and research for a real-time recommendation at OLX
Challenges and research for a real-time recommendation at OLX
 
Inteligência Artificial: Da ciência da computação à ciência de dados
Inteligência Artificial: Da ciência da computação à ciência de dadosInteligência Artificial: Da ciência da computação à ciência de dados
Inteligência Artificial: Da ciência da computação à ciência de dados
 
Machine Learning no dia a dia do desenvolvedor (Atualizado)
Machine Learning no dia a dia do desenvolvedor (Atualizado)Machine Learning no dia a dia do desenvolvedor (Atualizado)
Machine Learning no dia a dia do desenvolvedor (Atualizado)
 
Machine Learning no dia a dia do desenvolvedor
Machine Learning no dia a dia do desenvolvedorMachine Learning no dia a dia do desenvolvedor
Machine Learning no dia a dia do desenvolvedor
 
Experimentation anti patterns
Experimentation anti patternsExperimentation anti patterns
Experimentation anti patterns
 
Machine Learning e experimentos online para evitar o cancelamento no GloboPlay
Machine Learning e experimentos online para evitar o cancelamento no GloboPlayMachine Learning e experimentos online para evitar o cancelamento no GloboPlay
Machine Learning e experimentos online para evitar o cancelamento no GloboPlay
 
A ciência de dados por traz de sistemas de recomendação
A ciência de dados por traz de sistemas de recomendaçãoA ciência de dados por traz de sistemas de recomendação
A ciência de dados por traz de sistemas de recomendação
 
xCLiMF
xCLiMFxCLiMF
xCLiMF
 
Rastros digitais
Rastros digitaisRastros digitais
Rastros digitais
 
Big data
Big dataBig data
Big data
 
Recomendação de ponta a ponta na Globo.com
Recomendação de ponta a ponta na Globo.comRecomendação de ponta a ponta na Globo.com
Recomendação de ponta a ponta na Globo.com
 
Recomendação na Globo.com
Recomendação na Globo.comRecomendação na Globo.com
Recomendação na Globo.com
 
Otimizando seu projeto Rails
Otimizando seu projeto RailsOtimizando seu projeto Rails
Otimizando seu projeto Rails
 
Testes unitários e de integração: Quando e Porque
Testes unitários e de integração: Quando e PorqueTestes unitários e de integração: Quando e Porque
Testes unitários e de integração: Quando e Porque
 
Redis na Prática
Redis na PráticaRedis na Prática
Redis na Prática
 
Dinamizando Sites Estáticos
Dinamizando Sites EstáticosDinamizando Sites Estáticos
Dinamizando Sites Estáticos
 
Escalando Sites com Nginx
Escalando Sites com NginxEscalando Sites com Nginx
Escalando Sites com Nginx
 

Meta-programacao em python

  • 1. Metaprogramação em Python Para ajudar em nosso dia a dia    
  • 2. Metaprogramação Programação: Dados → Código → Dados Metaprogramação: Programa → Código → Programa    
  • 3. Metaprogramação ● Refletir ● Alterar ● Estender    
  • 4. Metaprogramação em python ● Tudo é objeto, tudo é atribuível ● Method missing ● Metaclasses ● Builtins types    
  • 5. Classe tradicional class Pessoa(object): def __init__(self, nome): self.nome = nome def andar(self, metros): print "%s andou %d metros" % (self.nome, metros) eu = Pessoa("Tiago") eu.andar(10)    
  • 6. Outra maneira de criar def construtor(self, nome): self.nome = nome def andar(self, metros): print "%s andou %d metros" % (self.nome, metros) Pessoa = type("Pessoa", (object,), { "__init__": construtor, "andar": andar })    
  • 7. Reflexão print eu.__class__ > <class '__main__.Pessoa'> print Pessoa.__class__ > <type 'type'> print Pessoa.__bases__ > (<type 'object'>,) print Pessoa.__dict__ > {'andar': <function andar at 0x7f27b159e230>, … } print eu.__dict__ > {'nome': 'Tiago'}    
  • 8. Métodos na classe def cantar(self, musica): print u"%s cantou ♪ %s ♪" % (self.nome, musica) Pessoa.cantar = cantar eu = Pessoa("Tiago") eu.cantar("Pra Sonhar") > Tiago cantou ♪ Pra Sonhar ♪ ela = Pessoa("Zilah") ela.cantar("Felicidade")   > Zilah cantou ♪ Felicidade ♪  
  • 9. Métodos na instância def cantar(self, musica): print u"%s cantou ♪ %s ♪" % (self.nome, musica) from types import MethodType eu.cantar = MethodType(cantar, eu) eu.cantar("Pra Sonhar") > Tiago cantou ♪ Pra Sonhar ♪ ela.cantar("Felicidade") > AttributeError: 'Pessoa' object has no   attribute 'cantar'  
  • 10. Adicionando superclasses class CantorMixin(): def cantar(self, musica): print u"%s cantou ♪ %s ♪" % (self.nome, musica) eu = Pessoa("Tiago") Pessoa.__bases__ += (CantorMixin,) eu.cantar("Pra Sonhar")    
  • 11. Qual utilidade? Alguns exemplos    
  • 12. 1- Stub para teste class TestUser(TestCase): def test_friends_names(self): friends = [{'name': 'Bruno'},{'name':'Renan'}] Facebook.get_friends = lambda obj: friends returned = User().friends_names() assert returned == ['Bruno','Renan'] def setUp(self): self.__get_friends = Facebook.get_friends def tearDown(self): Facebook.get_friends = self.__get_friends    
  • 13. 2- Estender frameworks class ExtendedFindersMixin(): def cached(self): #... def paged(self, page=None, size=None): #... Manager.__bases__ += (ExtendedFindersMixin, ) QuerySet.__bases__ += (ExtendedFindersMixin, ) #Usando: User.objects.filter(age__gte=18).paged(1,10).cached()    
  • 14. 3- NullObjects sem Factory class UserQuiz(object): def __init__(self, id): if not id: self.null_object() def null_object(self): self.answer = MethodType(lambda a: False, self) self.answer_list = MethodType(lambda a: [], self) def answer(self): #... def answer_list(self): #...    
  • 15. Metaprogramação em python ● Tudo é objeto, tudo é atribuível ● Method missing ● Metaclasses ● Builtins types    
  • 16. Attribute missing class Pessoa(object): def __init__(self, nome): self.nome = nome def __getattr__(self, attr): return "%s nao possui o atributo %s" % (self.nome, attr) eu = Pessoa("Tiago") print eu.nome → Tiago print eu.idade → Tiago nao possui o atributo idade    
  • 17. Method missing class Pessoa(object): def __getattr__(self, attr): def tentar(*args): print "%s tentou %s (%s)" % (self.nome, attr, args) return tentar def andar(self, metros): print "%s andou %s metros" % (self.nome, metros) eu = Pessoa("Tiago") eu.andar(10) →Tiago andou 10 metros eu.falar("Blablabla") →Tiago tentou falar (('Blablabla',))    
  • 18. Operadores class Pessoa(object): def multiplicar(self, v): return [ Pessoa(self.nome) for i in range(v) ] def soma(self, v): return Pessoa(self.nome[0:3]+v.nome[0:3]) __mul__ = multiplicar __add__ = soma print Pessoa("Smith") * 3 → ['Smith', 'Smith', 'Smith'] print (Pessoa("Tiago") + Pessoa("Zilah")).nome → "TiaZil”    
  • 19. Qual utilidade? Alguns exemplos    
  • 20. Lazy load class SemanticEntity(object): def __init__(self, uri): self.uri = uri self.attrs = None def __getattr__(self, attr): self.__lazy_load() val = self.attrs.get(attr) if self.__is_entity(val): return self.__class__(val) return val def __lazy_load(self): if self.attrs is None: self.__load()    
  • 21. Lazy load eu = SemanticEntity("http://globo.com/tiago”) print eu.nome → Tiago print eu.apaixonado_por.nome → Zilah print eu.apaixonado_por.uri → http://globo.com/zilah print eu.apaixonado_por.apaixonado_por.nome → Tiago    
  • 22. Conquistar uma namorada class Pessoa(object): def coracao(self, v): if v == 3: return "Zilah" __lt__ = coracao tiago = Pessoa() print tiago <3    
  • 23. Metaprogramação em python ● Tudo é objeto, tudo é atribuível ● Method missing ● Metaclasses ● Builtins types    
  • 24. O que é? Classe: → Fábica de instâncias Metaclasse: → Fábrica de classes    
  • 25. Metaclasse... chata class MetaClasseChata(type): def __new__(cls, name, bases, dct): print "Alocando memoria para %s" % name return type.__new__(cls, name, bases, dct) def __init__(cls, name, bases, dct): print "Criando classe %s" % name super(MetaClasseChata, cls).__init__(name,bases,dct) def metodo_da_classe(cls): print "Metodo da classe"    
  • 26. Metaclasse... chata class ClasseChata(object): __metaclass__ = MetaClasseChata print ClasseChata.metodo_da_classe() print type(ClasseChata) ---------------------------------------------------- Alocando memoria para ClasseChata Criando classe ClasseChata Metodo da classe <class '__main__.MetaClasseChata'>    
  • 27. Um exemplo legal Selfless python Por João Sebastião de Oliveira Bueno http://metapython.blogspot.com    
  • 28. Mas antes: Descriptors from random import random class NumeroAleatorioDescriptor(object): def __get__(self, instance, classe): return int(random()*100) class Roleta(object): valor = NumeroAleatorioDescriptor() print Roleta().valor    
  • 29. Selfless python class SelflessDescriptor(object): def __init__(self, func): self.func = func def __get__(self, instance, class_): new_globals = self.func.func_globals.copy() new_globals["self"] = instance new_func = FunctionType(self.func.func_code, new_globals, self.func.func_name, self.func.func_defaults, self.func.func_closure) return new_func class Selfless(type): def __new__(cls, name, bases, dict_): for key, val in dict_.items(): if isinstance(val, FunctionType): dict_[key] = SelflessDescriptor(val)   return type(name, bases, dict_)  
  • 30. Selfless python __metaclass__ = Selfless class A: def __init__(a, b): self.a = a self.b = b    
  • 31. Metaprogramação em python ● Tudo é objeto, tudo é atribuível ● Method missing ● Metaclasses ● Builtins types    
  • 32. Fuuuuuuuu from datetime import datetime datetime.now = lambda: None TypeError: can't set attributes of built-in/extension type 'datetime.datetime' set.get = lambda: None TypeError: can't set attributes of built-in/extension type 'set' list.index = lambda i: None TypeError: can't set attributes of built-in/extension type 'list' str.split = lambda: None TypeError: can't set attributes of built-in/extension type 'str'    
  • 33. Datetime: Jeitinho brasileiro import datetime as dt_module from datetime import datetime class TestArtist(TestCase): def test_should_find_news_by_date(self): today = datetime.today() dt_module.datetime = DateTimeFake(today) def get_by_date_fake(obj, date): self.used_date = date return [] NewsRepository.get_by_date = get_by_date_fake Artist().news() assert self.used_date == today    
  • 34. O jeito é uma herancinha com você class BetterDict(dict): def __getattr__(self, attr): return self.__getitem__(attr) def __setattr__(self, attr, val): self.__setitem__(attr, val) x = BetterDict({'a': 'A'}) x['b'] = 'B' x.c = 'C' print x.a, x.b, x.c → A B C print x['a'], x['b'], x['c'] → A B C    
  • 35. O jeito é uma herancinha com você class BetterList(list): def subtraction(self, other): for i in other: if i in self: self.remove(i) return self __isub__ = subtraction x = BetterList([1,2,3,4]) x -= [2, 4] print x → [1, 3]    
  • 36. Outras coisas legais... … mas que não são metaprogramação ● Decorators ● With Statement ● Multiprocessing    
  • 37. Conclusão ● Ruby ● Python ● Java