Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Metaprogramação em Python

Metaprogramação em Python

Palestra realizada na PySM

More Decks by Evandro Leopoldino Gonçalves

Other Decks in Programming

Transcript

  1. Sobre mim • Evandro Leopoldino Gonçalves, 28 • @evandrolg (Github,

    Twitter, Medium, etc) • Eventer - http://www.eventer.com.br • Pegasus.lua - http://evandrolg.github.io/ pegasus.lua/
  2. • Escrever programas para ler, gerar ou transformar outros programas

    e modificar ele mesmo • Escrever código que manipula as construções da linguagem (classes, funções, variáveis de instancia, módulos) • Código que manipula código!
  3. Python básico • Em Python tudo é um objeto
 (Classes,

    funções, tipos, módulos) • Os objetos tem métodos mágicos
 (obj.__new__, obj.__prepare__) • Python tem suporte a closures • Desde a versão 3, Python tem suporte a annotations
  4. • É a habilidade de um programa analisar e executar

    a estrutura de um programa em runtime
  5. • @my_first_decorator
 def get_name():
 """" Returns my name """
 return

    'Evandro'
 
 print(get_name())
 # <p>Evandro</p>
 
 print(get_name.__name__)
 # wrap
 
 print(get_name.__doc__)
 # None
  6. • from functools import wraps
 
 def my_first_decorator(func):
 @wraps(func) 


    def wrap():
 return ‘<p>%s</p>’ % fn()
 return wrap

  7. • def changelist(func):
 def wrap(self, request, *args, **kwargs):
 model =

    self.model
 if not has_permission(request, model):
 raise Exception() 
 if re.search('^/e/(\w+)/(\w+)/$', request.path):
 return func(self, request)\
 .filter(event=request.GET[‘e’])
 return func(self, request)
 return wrap
  8. • class Person:
 name = property()
 
 @name.getter
 def name(self):


    return self._name
 
 @name.setter
 def name(self, value):
 if not isinstance(value, str):
 raise TypeError('Expected a string')
 self._name = value
  9. • from inspect import signature
 
 def type_check(func):
 def wrap(*args,

    **kwargs):
 for key, param in enumerate(signature(func).parameters.values()):
 if not isinstance(args[key], param.annotation):
 raise Exception('Expected %s type and %s received ' 
 % (type(args), param.annotation))
 
 return func(*args, **kwargs)
 return wrap
  10. • Em Python, uma classe é um outro objeto, ou

    seja é a instancia de alguma coisa: uma metaclasse! • Metaclasse é uma instancia de type
  11. • def method(self):
 print(‘My method!’)
 
 MyClass = type(‘MyClass’, (),

    dict(method=method))
 
 m = MyClass()
 m.method()
 # My method!
  12. • from inspect import isfunction
 from datetime import datetime
 


    class Logger(type):
 def __init__(self, namespece, bases, attributes):
 for key in attributes:
 func = attributes[key]
 
 if isfunction(func):
 print(func.__name__, datetime.now())
  13. • class Person(metaclass=Logger):
 def speak(self, message):
 print(message)
 
 def walk(self):


    print(‘walking…’)
 
 person = People()
 
 person.speak('hello world!')
 # speak 2015-08-23 22:53:11.615184 (<__main__.People object at 0x1006000b8>, 'hello world!')
 # hello world!
 
 person.walk()
 # run 2015-08-23 22:53:11.615947 (<__main__.People object at 0x1006000b8>,)
 # walking…