O documento apresenta os conceitos básicos de metaprogramação em Python, incluindo reflexão, decorators, propriedades e metaclasses. A metaprogramação permite escrever código que manipula outros programas ou modifica a si mesmo, como compiladores ou decoradores de funções. Em Python, tudo é um objeto e os objetos têm métodos mágicos que permitem a análise e execução de código em tempo de execução.
4. • 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!
6. 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
19. • 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
21. • 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
24. • Em Python, uma classe é um outro objeto, ou seja
é a instancia de alguma coisa: uma metaclasse!
• Metaclasse é uma instancia de type
25. • def method(self):
print(‘My method!’)
MyClass = type(‘MyClass’, (), dict(method=method))
m = MyClass()
m.method()
# My method!
26. • 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())
27. • 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…