Python para quem sabe Python

Propaganda
Python para quem sabe Python
Turma 0, aula 4
Metaclasses,
programação funcional
e programação assíncrona
Exercício: execucao.py
●
●
●
●
Para entender como o interpretador Python lê
um arquivo .py
Tudo é executável
Mas às vezes, executar significa “definir,
compilar e atribuir um objeto” (ex. funções e
classes)
O que é preciso executar para definir um
desses objetos?
https://github.com/oturing/ppqsp/blob/master/metaprog/execucao.py
Recapitulando: Descritores
Recapitulando:
Descritores e metaclasses
Descritor com nome automático
class Quantidade(object):
def __set__(self, instance, valor):
# nome atribuido Just-In-Time, idéia do Gustavo Fonseca [1]
if not hasattr(self, 'nome_atr'):
for nome, atr in instance.__class__.__dict__.items():
if atr is self:
self.nome_atr = '__'+nome
break
else: # only if the for loop terminates without break
assert False, 'descriptor not found in class'
if valor < 1:
raise TypeError('%s deve ser > 0' % self.nome_atr[2:])
setattr(instance, self.nome_atr, valor)
def __get__(self, instance, owner):
return getattr(instance, self.nome_atr)
class C(object):
def __init__(self, x):
self.x = x
x = Quantidade()
[1] http://gusfonseca.wordpress.com/2011/12/11/um-pouco-sobre-descritores-em-python/
O caminho até metaclasses
●
No github.com/oturing/ppsqp [1]
●
pedido3.py: descritor com nome automático
●
pedido4.py e pedido5.py:
●
●
primeiro exemplo do atributo __metaclass__
classe abstrata ValidatedDescriptor para facilitar a
criação de novos descritores com validação
–
uso do padrão Template Method (GoF 325)
[1] https://github.com/oturing/ppqsp/tree/master/atributos/metaclasses
Template Method (GoF 325)
●
●
Auto-delegação (A. Martelli)
Usando Template Method,
uma classe abstrata deixa suas
subclasses definirem um ou
mais passos de um algoritmo
O caminho até metaclasses (2)
●
pedido6.py:
●
●
registro da ordem dos descritores via
ValidatedDescriptor.__new__
primeiro exemplo do método __new__
O caminho até metaclasses (3)
●
pedido7.py:
●
●
●
metaclasse OrderedModelMeta para criar atributo
_ordered_descriptors em cada nova classe deste tipo
classe OrderedModel para facilitar o uso da metaclasse,
permitindo que as subclasses herdem o atributo
__metaclass__ = OrderedModelMeta
registro da ordem dos descritores movido de
ValidatedDescriptor para a nova classe abstrata
OrderedDescriptor
–
separação de responsabilidades: uma classe cuida de
validação, a outra de ordenação
O caminho até metaclasses (4)
●
pedido8.py:
●
lógica de atribuição de nomes aos descritores movida
para o método __new__ da metaclasse
OrderedModelMeta
–
●
aproveita o fato de que este método __new__ já tem que
percorrer todos os atributos do dict da nova classe, e evita o
custo de fazer um laço a cada __set__ inicial e um teste
hasattr em todas as chamadas de __set__
método list_ordered_descriptors na classe
OrderedModel para evitar que as subclasses tenha que
acessar o atributo de classe que mantém a lista
(_ordered_descriptors)
O caminho até metaclasses (5)
●
pedido9.py:
●
●
definição de um __init__ genérico em
OrderedModel que recebe os argumentos
posicionais e os atribui em aos atributos ordenados
desta forma as subclasses de OrderedModel não
precisam implementar seus __init__, evitando a
repetição dos nomes dos atributos associados aos
OrderedDescriptors
Programação funcional
●
Paradigma que enfatiza o uso de funções puras,
composição de funções, funções de ordem superior
e estruturas de dados imutáveis
●
●
●
Funções puras = sem efeitos colaterais: não modificam
seus argumentos nem alteram o estado do sistema de
nenhuma maneira, mas apenas devolvem um valor
Composição de funções: aplicação de uma função ao
resultado de uma outra
Funções de ordem superior: funções que recebem
funções como argumentos ou devolvem funções como
resultado
Funções como objetos de 1ª classe
●
objetos de 1ª classe
●
ex: números, strings, listas, etc. (até classes em Python)
●
podem ser construídos em tempo de execução
●
●
em Python, funções são objetos de 1ª classe
●
●
podem ser atribuídos a variáveis, passados como
argumentos, devolvidos como resultados de funções
isso ocorre em muitas linguagens modernas, mas não em
Java e nem em Pascal
em Python, funções são instâncias de function, e têm
seus próprios atributos
Funções são objetos de 1ª classe
função de
ordem superior
>>>
>>> def
def dobro(n):
dobro(n):
...
"""Devolve
...
"""Devolve duas
duas vezes
vezes n"""
n"""
...
return
...
return n*2
n*2
>>>
>>> dobro(21)
dobro(21)
42
42
>>>
>>> dobro('X')
dobro('X')
'XX'
'XX'
>>>
>>> dobro
dobro
<function
<function dobro
dobro at
at 0x990b17c>
0x990b17c>
>>>
>>> type(dobro)
type(dobro)
<type
<type 'function'>
'function'>
>>>
>>> x2
x2 == dobro
dobro
>>>
>>> x2(1234)
x2(1234)
2468
2468
>>>
>>> map(dobro,
map(dobro, [11,
[11, 22,
22, 33])
33])
[22,
[22, 44,
44, 66]
66]
Funções de ordem superior
●
●
Funções que recebem funções como argumento
ou devolvem funções como resultado
Exemplos importantes em Python:
●
map, filter
–
●
reduce
–
●
fazem o mesmo que list comprehensions
substituído por sum, all e any nos casos mais comuns
sorted, list.sort
–
muito úteis
Recursos para programação
funcional em Python
●
Módulo functools
●
●
Módulo itertools
●
●
várias funções de ordem superior
inspirado pelas biblioteca padrão de Haskell, uma
das linguagens funcionais mais “puras”
Módulo operator
●
●
operadores básicos de Python implementados
como funções
muito úteis: attrgetter e itemgetter
Programação asíncrona
Programação assíncrona
●
●
Também conhecida como programação
orientada a eventos
Aplicações: sistemas reativos
●
●
●
reagem a eventos externos
ex: servidores, aplicações GUI, jogos,
controladores embutidos em máquinas
Na moda por causa do problema C10k
●
como lidar com 10.000 conexões?
–
10.000 threads não é a resposta certa
Bibliotecas para programação de
aplicações de rede assíncronas
●
●
Módulos select, asyncore e asyncchat do
Python padrão
Twisted: 10 anos de história, muitos protocolos,
tem uma cultura e terminologia própria, peculiar
●
baseado em callbacks, com suporte recente a corotinas
●
Tornado: recente, mais enxuto que o Twisted
●
gevent: baseado em co-rotinas
●
outras opções...
Temas I
●
●
●
sobrecarga de operadores (ou como fazer uma
API Pythonica)
iteráveis e iteradores (ou como percorrer
qualquer coisa com um simples for)
geradores e co-rotinas (ou outro jeito de
organizar meus algoritmos)
Temas II
●
●
●
●
acesso, criação e remoção dinânica de
atributos (tudo sobre atributos básicos)
propriedades e descritores (encapsulamento
com atributos, ou como funcionam os modelos
do Django)
meta-programação, criação dinâmica de
classes e funções (ou monkeypatching)
metaclasses (ou como explodir sua mente
criando classes turbinadas)
Temas III
●
●
●
●
programação funcional (ou aquele outro
paradigma que tá na moda)
decoradores de funções (ou meta-programação
com arte)
programação assíncrona (ou como fazer
muitas coisas ao mesmo tempo sem usar
threads)
gerenciadores de contexto (ou como usar o
comando with)
Download