python: iteraveis, geradores etc
DESCRIPTION
TRANSCRIPT
![Page 2: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/2.jpg)
![Page 3: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/3.jpg)
@ramalhoorg
Luciano Ramalho
• Arquiteto de soluções Web desde 1994
• 1º diretor técnico do Brasil Online, na Abril S/A
• Muitos clientes e alguns empregos desde então, quase sempre atuando na Web (server-side)
• Atualmente: Oficinas Turing (vários cursos) e Academia Python em parceria com Globalcode
• Sócio do Garoa Hacker Clube
![Page 4: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/4.jpg)
![Page 5: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/5.jpg)
![Page 6: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/6.jpg)
@ramalhoorg
Exemplos
• Laço for em Python iterando sobre:
• string
• arquivo
• Django QuerySet
• Baralho
![Page 7: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/7.jpg)
@ramalhoorg
Contraste• laço for em BASIC, Pascal, C
• muito bons para incrementar inteiros!
• “foreach” em JavaScript, Bash
• parecidos com o de Python, mas limitados aos tipos primitivos da linguagem
• “foreach” em Java
• “enhanced for” no Java 5
![Page 8: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/8.jpg)
@ramalhoorg
Em Python o comando for itera sobre... “iteráveis”• Literalmente:
• “desmontável” = que pode ser desmontado
• “iterável” = que pode ser iterado
• E como se faz um objeto iterável em Python?
• forma legada: protocolo de sequência
• forma moderna: interface Iterable
![Page 9: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/9.jpg)
@ramalhoorg
Interface? Em Python?(P. S. Canning, W. R. Cook, W. L. Hill, and W. G. Olthoff. 1989. Interfaces for strongly-typed object-oriented programming. In Conference proceedings on Object-oriented programming systems, languages and applications (OOPSLA '89). ACM, New York, NY, USA, 457-467. DOI=10.1145/74877.74924 http://doi.acm.org/10.1145/74877.74924
The interface provides a boundary between the implementations of an abstraction and its clients. It limits the amount of implementation detail visible to clients. It also specifies the functionality that implementations must provide.
• Interface é um conceito essencial em OO
• Em Smalltalk: “protocolo”
![Page 10: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/10.jpg)
@ramalhoorg
Interface? Em Python?• Interface é um conceito essencial em OO
• Em Smalltalk: “protocolo”(P. S. Canning, W. R. Cook, W. L. Hill, and W. G. Olthoff. 1989. Interfaces for strongly-typed object-oriented programming. In Conference proceedings on Object-oriented programming systems, languages and applications (OOPSLA '89). ACM, New York, NY, USA, 457-467. DOI=10.1145/74877.74924 http://doi.acm.org/10.1145/74877.74924
A interface fornece uma separação entre a implementação de uma abstração e seus clientes. Ela limita os detalhes de implementação que os clientes podem ver. Também especifica a funcionalidade que as implementações devem prover.
![Page 11: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/11.jpg)
@ramalhoorg
Interface em Python
• Conceitualmente, sempre existiram
• Não havia maneira formal de especificar interfaces em Python até a versão 2.5
• usava-se termos como “uma sequência” ou “a file-like object”
• Agora temos ABC (Abstract Base Class)
• com herança múltipla, como em C++
)
![Page 12: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/12.jpg)
@ramalhoorg
Em Python, um iterável é...
• Um objeto a partir do qual a função iter consegue obter um iterador.
• A chamada iter(x):
• invoca x.__iter__() para obter um iterador
• ou, se x.__iter__ não existe:
• fabrica um iterador que acessa os itens de x sequenciamente fazendo x[0], x[1], x[2] etc.
![Page 13: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/13.jpg)
@ramalhoorg
Protocolo de sequência>>> t = Trem(4)>>> len(t)4>>> t[0]'vagao #1'>>> t[3]'vagao #4'>>> t[-1]'vagao #4'>>> for vagao in t:... print(vagao)vagao #1vagao #2vagao #3vagao #4
__len__
__getitem__
__getitem__
![Page 14: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/14.jpg)
@ramalhoorg
class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __len__(self): return self.num_vagoes def __getitem__(self, pos): indice = pos if pos >= 0 else self.num_vagoes + pos if 0 <= indice < self.num_vagoes: # indice 2 -> vagao #3 return 'vagao #%s' % (indice+1) else: raise IndexError('vagao inexistente %s' % pos)
Protocolo de sequência
• collections.Sequence
![Page 15: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/15.jpg)
@ramalhoorg
InterfaceIterable
• Iterable provê um método __iter__
• O método __iter__ devolve uma instância de Iterator
![Page 16: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/16.jpg)
@ramalhoorg
Iterator é...
• um padrão de projeto
Design PatternsGamma, Helm, Johnson & VlissidesAddison-Wesley, ISBN 0-201-63361-2
![Page 17: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/17.jpg)
@ramalhoorg
Head First Design Patterns PosterO'Reilly, ISBN 0-596-10214-3
![Page 18: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/18.jpg)
@ramalhoorg
O padrão Iterator permite acessar os itens de uma coleção sequencialmente, isolando o cliente da implementação da coleção.
Head First Design Patterns PosterO'Reilly, ISBN 0-596-10214-3
![Page 19: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/19.jpg)
@ramalhoorg
• for vagao in t:
• invoca iter(t)
• devolve IteradorTrem
• invoca itrem.next() até que ele levante StopIteration
class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): return IteradorTrem(self.num_vagoes)
class IteradorTrem(object): def __init__(self, num_vagoes): self.atual = 0 self.ultimo_vagao = num_vagoes - 1 def next(self): if self.atual <= self.ultimo_vagao: self.atual += 1 return 'vagao #%s' % (self.atual) else: raise StopIteration()
Tremcomiterator
>>> t = Trem(4)>>> for vagao in t:... print(vagao)vagao #1vagao #2vagao #3vagao #4
iter(t)
![Page 20: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/20.jpg)
@ramalhoorg
Em Python, um iterável é...
• Um objeto a partir do qual a função iter consegue obter um iterador.
• A chamada iter(x):
• invoca x.__iter__() para obter um iterador
• ou, se x.__iter__ não existe:
• fabrica um iterador que acessa os itens de x sequenciamente fazendo x[0], x[1], x[2] etc.
protocolo de sequência
interface Iterable
![Page 21: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/21.jpg)
@ramalhoorg
Iterator x generator• Gerador é uma generalização do iterador
• Por definição, um objeto iterador produz itens iterando sobre outro objeto (alguma coleção)
• Um objeto gerador produz itens de forma independente
• ele pode iterar sobre outro objeto mas também pode gerar itens por contra própria, sem qualquer dependência externa
![Page 22: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/22.jpg)
@ramalhoorg
Funçãogeradora
• Quando invocada, devolve um objeto gerador
• O objeto gerador é um iterável
>>> def g123():... yield 1... yield 2... yield 3... >>> for i in g123(): print i... 123>>> g = g123()>>> g<generator object g123 at 0x10e385e10>>>> g.next()1>>> g.next()2>>> g.next()3>>> g.next()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration
![Page 23: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/23.jpg)
@ramalhoorg
• for vagao in t:
• invoca iter(t)
• devolve gerador
• invoca gerador.next() até que ele levante StopIteration
class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): for i in range(self.num_vagoes): yield 'vagao #%s' % (i+1)
Trem c/ função geradora
>>> t = Trem(4)>>> for vagao in t:... print(vagao)vagao #1vagao #2vagao #3vagao #4
iter(t)
![Page 24: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/24.jpg)
class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): return IteradorTrem(self.num_vagoes)
class IteradorTrem(object): def __init__(self, num_vagoes): self.atual = 0 self.ultimo_vagao = num_vagoes - 1 def next(self): if self.atual <= self.ultimo_vagao: self.atual += 1 return 'vagao #%s' % (self.atual) else: raise StopIteration()
class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): for i in range(self.num_vagoes): yield 'vagao #%s' % (i+1)
Funçãogeradora
Iteradorclássico
12 linhasde código
3 linhas
mesma funcionalidade!
![Page 25: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/25.jpg)
@ramalhoorg
List comprehensions• Expressões que consomem iteráveis e
produzem listas
>>> s = 'abracadabra'>>> l = [ord(c) for c in s]>>> [ord(c) for c in s][97, 98, 114, 97, 99, 97, 100, 97, 98, 114, 97]
List comprehension
● Compreensão de lista ou abrangência de lista
● Exemplo: usar todos os elementos:
– L2 = [n*10 for n in L]
qualquer iterável
resultado: uma lista
![Page 26: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/26.jpg)
@ramalhoorg
Set & dict comprehensions• Expressões que consomem iteráveis e
produzem sets ou dicts
>>> s = 'abracadabra'>>> {c for c in s}set(['a', 'r', 'b', 'c', 'd'])>>> {c:ord(c) for c in s}{'a': 97, 'r': 114, 'b': 98, 'c': 99, 'd': 100}
![Page 27: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/27.jpg)
@ramalhoorg
Expressãogeradora
• Quando avaliada, devolve um objeto gerador
• O objeto gerador é um iterável
>>> g = (n for n in [1, 2, 3])>>> for i in g: print i... 123>>> g = (n for n in [1, 2, 3])>>> g<generator object <genexpr> at 0x109a4deb0>>>> g.next()1>>> g.next()2>>> g.next()3>>> g.next()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration
![Page 28: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/28.jpg)
@ramalhoorg
• for vagao in t:
• invoca iter(t)
• devolve gerador
• invoca gerador.next() até que ele levante StopIteration
class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): return ('vagao #%s' % (i+1) for i in range(self.num_vagoes))
Trem c/ expressão geradora
>>> t = Trem(4)>>> for vagao in t:... print(vagao)vagao #1vagao #2vagao #3vagao #4
iter(t)
![Page 29: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/29.jpg)
@ramalhoorg
Tipos iteráveis embutidos
• basestring
• str
• unicode
• dict
• file
• frozenset
• list
• set
• tuple
• xrange
![Page 30: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/30.jpg)
@ramalhoorg
Funções embutidas que consomem iteráveis• all
• any
• filter
• iter
• len
• map
• max
• min
• reduce
• sorted
• sum
• zip
![Page 31: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/31.jpg)
@ramalhoorg
Construtores embutidos que consomem e produzem iteráveis
• dict
• enumerate
• frozenset
• list
• reversed
• set
• tuple
![Page 32: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/32.jpg)
@ramalhoorg
Operações com iteráveis• Desempacotamento
de tupla
• em atribuições
• em chamadas de funções>>> def soma(a, b):... return a + b... >>> soma(1, 2)3>>> t = (3, 4)>>> soma(t)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: soma() takes exactly 2 arguments (1 given)>>> soma(*t)7
>>> a, b, c = 'XYZ'>>> a'X'>>> b'Y'>>> c'Z'>>> g = (n for n in [1, 2, 3])>>> a, b, c = g>>> a1>>> b2>>> c3
![Page 33: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/33.jpg)
@ramalhoorg
• geradores (potencialmente) infinitos
• count(), cycle(), repeat()
• geradores que combinam vários iteráveis
• chain(), tee(), izip(), imap(), product(), compress()...
• geradores que selecionam ou agrupam itens:
• compress(), dropwhile(), groupby(), ifilter(), islice()...
• Iteradores que produzem combinações
• product(), permutations(), combinations()...
Módulo itertools
![Page 34: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/34.jpg)
@ramalhoorg
Exemplo prático de função geradora
• Funções geradoras para desacoplar laços de leitura e escrita em uma ferramenta para conversão de bases de dados semi-estruturadas
https://github.com/ramalho/isis2json
![Page 35: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/35.jpg)
@ramalhoorg
Funções geradoras comoco-rotinas
• Segundo David Beazley, co-rotinas não tem a ver com iteração, e sim com pipelines
• então esse tema nem deveria ser tratado nesta palestra
• mas como são implementadas como funções geradoras, merece ser mencionado
![Page 36: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/36.jpg)
@ramalhoorg
Exemplo prático de co-rotina• Função geradora como co-rotina para preservar
o contexto de callback em programação assíncrona com o framework Tornado
https://github.com/oturing/ppqsp/.../async/assincrono_clo.py.../async/assincrono_ge.py
![Page 37: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/37.jpg)
oficina online:Objetos PythonicosPOO e padrões de projeto como devem ser em Python
Luciano [email protected]
@ramalhoorg
Pré-inscrição: pre-oopy.turing.com.br
![Page 38: Python: Iteraveis, geradores etc](https://reader034.vdocuments.net/reader034/viewer/2022052315/5496538aac79592f2e8b50b8/html5/thumbnails/38.jpg)