TDC2016POA | Trilha Python - Python Assíncrono: tudo ao mesmo tempo agora
Meta-programacao em python
-
Upload
tiago-albineli-motta -
Category
Technology
-
view
793 -
download
1
description
Transcript of Meta-programacao em python
![Page 1: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/1.jpg)
Metaprogramação em Python
Para ajudar em nosso dia a dia
![Page 2: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/2.jpg)
Metaprogramação
Programação:Dados → Código → Dados
Metaprogramação:Programa → Código → Programa
![Page 3: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/3.jpg)
Metaprogramação
● Refletir● Alterar● Estender
![Page 4: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/4.jpg)
Metaprogramação em python
● Tudo é objeto, tudo é atribuível● Method missing● Metaclasses● Builtins types
![Page 5: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/5.jpg)
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)
![Page 6: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/6.jpg)
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})
![Page 7: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/7.jpg)
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'}
![Page 8: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/8.jpg)
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 ♪
![Page 9: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/9.jpg)
Métodos na instância
def cantar(self, musica): print u"%s cantou ♪ %s ♪" % \ (self.nome, musica)
from types import MethodTypeeu.cantar = MethodType(cantar, eu)eu.cantar("Pra Sonhar")> Tiago cantou ♪ Pra Sonhar ♪
ela.cantar("Felicidade")> AttributeError: 'Pessoa' object has no attribute 'cantar'
![Page 10: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/10.jpg)
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")
![Page 11: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/11.jpg)
Qual utilidade?
Alguns exemplos
![Page 12: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/12.jpg)
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
![Page 13: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/13.jpg)
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()
![Page 14: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/14.jpg)
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): #...
![Page 15: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/15.jpg)
Metaprogramação em python
● Tudo é objeto, tudo é atribuível● Method missing● Metaclasses● Builtins types
![Page 16: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/16.jpg)
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 → Tiagoprint eu.idade → Tiago nao possui o atributo idade
![Page 17: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/17.jpg)
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 metroseu.falar("Blablabla") →Tiago tentou falar (('Blablabla',))
![Page 18: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/18.jpg)
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”
![Page 19: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/19.jpg)
Qual utilidade?
Alguns exemplos
![Page 20: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/20.jpg)
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()
![Page 21: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/21.jpg)
Lazy load
eu = 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
![Page 22: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/22.jpg)
Conquistar uma namorada
class Pessoa(object):
def coracao(self, v): if v == 3: return "Zilah" __lt__ = coracao
tiago = Pessoa()print tiago <3
![Page 23: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/23.jpg)
Metaprogramação em python
● Tudo é objeto, tudo é atribuível● Method missing● Metaclasses● Builtins types
![Page 24: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/24.jpg)
O que é?
Classe:→ Fábica de instâncias
Metaclasse:→ Fábrica de classes
![Page 25: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/25.jpg)
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"
![Page 26: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/26.jpg)
Metaclasse... chata
class ClasseChata(object): __metaclass__ = MetaClasseChata
print ClasseChata.metodo_da_classe()print type(ClasseChata)
----------------------------------------------------
Alocando memoria para ClasseChataCriando classe ClasseChataMetodo da classe<class '__main__.MetaClasseChata'>
![Page 27: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/27.jpg)
Um exemplo legal
Selfless pythonPor João Sebastião de Oliveira Bueno
http://metapython.blogspot.com
![Page 28: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/28.jpg)
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
![Page 29: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/29.jpg)
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_)
![Page 30: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/30.jpg)
Selfless python
__metaclass__ = Selfless
class A: def __init__(a, b): self.a = a self.b = b
![Page 31: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/31.jpg)
Metaprogramação em python
● Tudo é objeto, tudo é atribuível● Method missing● Metaclasses● Builtins types
![Page 32: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/32.jpg)
Fuuuuuuuu
from datetime import datetimedatetime.now = lambda: NoneTypeError: can't set attributes of built-in/extension type 'datetime.datetime'
set.get = lambda: NoneTypeError: can't set attributes of built-in/extension type 'set'
list.index = lambda i: NoneTypeError: can't set attributes of built-in/extension type 'list'
str.split = lambda: NoneTypeError: can't set attributes of built-in/extension type 'str'
![Page 33: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/33.jpg)
Datetime: Jeitinho brasileiro
import datetime as dt_modulefrom 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
![Page 34: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/34.jpg)
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 Cprint x['a'], x['b'], x['c'] → A B C
![Page 35: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/35.jpg)
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]
![Page 36: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/36.jpg)
Outras coisas legais...
… mas que não são metaprogramação
● Decorators● With Statement● Multiprocessing
![Page 37: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/37.jpg)
Conclusão
● Ruby● Python● Java
![Page 38: Meta-programacao em python](https://reader031.fdocumentos.tips/reader031/viewer/2022020110/55980b9c1a28ab302c8b46b4/html5/thumbnails/38.jpg)
Mantenha contato
@timotta
http://programandosemcafeina.blogspot.com