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...
Classe tradicional    class Pessoa(object):      def __init__(self, nome):        self.nome = nome      def andar(self, me...
Outra maneira de criar    def construtor(self, nome):      self.nome = nome    def andar(self, metros):      print "%s and...
Reflexão    print eu.__class__    > <class __main__.Pessoa>    print Pessoa.__class__    > <type type>    print Pessoa.__b...
Métodos na classe    def cantar(self, musica):      print u"%s cantou ♪ %s ♪" %               (self.nome, musica)    Pesso...
Métodos na instância    def cantar(self, musica):      print u"%s cantou ♪ %s ♪" %               (self.nome, musica)    fr...
Adicionando superclasses    class CantorMixin():       def cantar(self, musica):         print u"%s cantou ♪ %s ♪" % (self...
Qual utilidade?        Alguns exemplos                
1- Stub para testeclass TestUser(TestCase):     def test_friends_names(self):       friends = [{name: Bruno},{name:Renan}]...
2- Estender frameworksclass ExtendedFindersMixin():   def cached(self):     #...   def paged(self, page=None, size=None): ...
3- NullObjects sem Factoryclass UserQuiz(object):     def __init__(self, id):       if not id:           self.null_object(...
Metaprogramação em python    ●   Tudo é objeto, tudo é atribuível    ●   Method missing    ●   Metaclasses    ●   Builtins...
Attribute missingclass Pessoa(object):     def __init__(self, nome):       self.nome = nome     def __getattr__(self, attr...
Method missingclass Pessoa(object):     def __getattr__(self, attr):       def tentar(*args):          print "%s tentou %s...
Operadoresclass Pessoa(object):   def multiplicar(self, v):     return [ Pessoa(self.nome) for i in range(v) ]   def soma(...
Qual utilidade?        Alguns exemplos                
Lazy loadclass SemanticEntity(object):     def __init__(self, uri):       self.uri = uri       self.attrs = None     def _...
Lazy loadeu = SemanticEntity("http://globo.com/tiago”)print eu.nome → Tiagoprint eu.apaixonado_por.nome → Zilahprint eu.ap...
Conquistar uma namorada    class Pessoa(object):      def coracao(self, v):        if v == 3:           return "Zilah"    ...
Metaprogramação em python    ●   Tudo é objeto, tudo é atribuível    ●   Method missing    ●   Metaclasses    ●   Builtins...
O que é?    Classe:    → Fábica de instâncias    Metaclasse:    → Fábrica de classes                      
Metaclasse... chataclass MetaClasseChata(type):    def __new__(cls, name, bases, dct):      print "Alocando memoria para %...
Metaclasse... chataclass ClasseChata(object):   __metaclass__ = MetaClasseChataprint ClasseChata.metodo_da_classe()print t...
Um exemplo legal               Selfless python    Por João Sebastião de Oliveira Bueno       http://metapython.blogspot.co...
Mas antes: Descriptors    from random import random    class NumeroAleatorioDescriptor(object):       def __get__(self, in...
Selfless pythonclass SelflessDescriptor(object):   def __init__(self, func):     self.func = func   def __get__(self, inst...
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...
Fuuuuuuuufrom datetime import datetimedatetime.now = lambda: NoneTypeError: cant set attributes of built-in/extension     ...
Datetime: Jeitinho brasileiroimport datetime as dt_modulefrom datetime import datetimeclass TestArtist(TestCase):   def te...
O jeito é uma herancinhacom vocêclass BetterDict(dict):    def __getattr__(self, attr):      return self.__getitem__(attr)...
O jeito é uma herancinhacom vocêclass BetterList(list):    def subtraction(self, other):      for i in other:         if i...
Outras coisas legais...        … mas que não são metaprogramação    ●   Decorators    ●   With Statement    ●   Multiproce...
Conclusão    ●   Ruby    ●   Python    ●   Java                  
Mantenha contatotimotta@gmail.com@timottahttp://programandosemcafeina.blogspot.com                      
Upcoming SlideShare
Loading in …5
×

Meta-programacao em python

1,077 views

Published on

Palestra sobre meta-programação em python ministrada no TDC 2012 e na SEMCOMP 2012. Corrigido o verbo "estender" que estava antes "extender" e colocado realce de sintaxe.

Published in: Technology, Education
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,077
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
43
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Meta-programacao em python

  1. 1. Metaprogramação em Python Para ajudar em nosso dia a dia   
  2. 2. Metaprogramação Programação: Dados → Código → Dados Metaprogramação: Programa → Código → Programa   
  3. 3. Metaprogramação ● Refletir ● Alterar ● Estender   
  4. 4. Metaprogramação em python ● Tudo é objeto, tudo é atribuível ● Method missing ● Metaclasses ● Builtins types   
  5. 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. 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. 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. 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. 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. 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. 11. Qual utilidade? Alguns exemplos   
  12. 12. 1- Stub para testeclass 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. 13. 2- Estender frameworksclass 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. 14. 3- NullObjects sem Factoryclass 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. 15. Metaprogramação em python ● Tudo é objeto, tudo é atribuível ● Method missing ● Metaclasses ● Builtins types   
  16. 16. Attribute missingclass 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 → Tiagoprint eu.idade → Tiago nao possui o atributo idade    
  17. 17. Method missingclass 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 metroseu.falar("Blablabla") →Tiago tentou falar ((Blablabla,))    
  18. 18. Operadoresclass 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__ = somaprint Pessoa("Smith") * 3 → [Smith, Smith, Smith]print (Pessoa("Tiago") + Pessoa("Zilah")).nome → "TiaZil”    
  19. 19. Qual utilidade? Alguns exemplos   
  20. 20. Lazy loadclass 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. 21. Lazy loadeu = SemanticEntity("http://globo.com/tiago”)print eu.nome → Tiagoprint eu.apaixonado_por.nome → Zilahprint eu.apaixonado_por.uri → http://globo.com/zilahprint eu.apaixonado_por.apaixonado_por.nome → Tiago    
  22. 22. Conquistar uma namorada class Pessoa(object): def coracao(self, v): if v == 3: return "Zilah" __lt__ = coracao tiago = Pessoa() print tiago <3   
  23. 23. Metaprogramação em python ● Tudo é objeto, tudo é atribuível ● Method missing ● Metaclasses ● Builtins types   
  24. 24. O que é? Classe: → Fábica de instâncias Metaclasse: → Fábrica de classes   
  25. 25. Metaclasse... chataclass 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. 26. Metaclasse... chataclass ClasseChata(object): __metaclass__ = MetaClasseChataprint ClasseChata.metodo_da_classe()print type(ClasseChata)----------------------------------------------------Alocando memoria para ClasseChataCriando classe ClasseChataMetodo da classe<class __main__.MetaClasseChata>    
  27. 27. Um exemplo legal Selfless python Por João Sebastião de Oliveira Bueno http://metapython.blogspot.com   
  28. 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. 29. Selfless pythonclass 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_funcclass 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. 30. Selfless python __metaclass__ = Selfless class A: def __init__(a, b): self.a = a self.b = b   
  31. 31. Metaprogramação em python ● Tudo é objeto, tudo é atribuível ● Method missing ● Metaclasses ● Builtins types   
  32. 32. Fuuuuuuuufrom datetime import datetimedatetime.now = lambda: NoneTypeError: cant set attributes of built-in/extension type datetime.datetimeset.get = lambda: NoneTypeError: cant set attributes of built-in/extension type setlist.index = lambda i: NoneTypeError: cant set attributes of built-in/extension type liststr.split = lambda: NoneTypeError: cant set attributes of built-in/extension type str   
  33. 33. Datetime: Jeitinho brasileiroimport datetime as dt_modulefrom datetime import datetimeclass 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. 34. O jeito é uma herancinhacom 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] = Bx.c = Cprint x.a, x.b, x.c → A B Cprint x[a], x[b], x[c] → A B C   
  35. 35. O jeito é uma herancinhacom vocêclass BetterList(list): def subtraction(self, other): for i in other: if i in self: self.remove(i) return self __isub__ = subtractionx = BetterList([1,2,3,4])x -= [2, 4]print x → [1, 3]   
  36. 36. Outras coisas legais... … mas que não são metaprogramação ● Decorators ● With Statement ● Multiprocessing   
  37. 37. Conclusão ● Ruby ● Python ● Java   
  38. 38. Mantenha contatotimotta@gmail.com@timottahttp://programandosemcafeina.blogspot.com   

×