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

Metaprogramação em Python

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

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…