SlideShare ist ein Scribd-Unternehmen logo
1 von 38
Downloaden Sie, um offline zu lesen
Luciano Ramalho
                              luciano@ramalho.org
                                      @ramalhoorg




Iteráveis, geradores & cia:
a essência do Python
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
                                              @ramalhoorg
Exemplos

• Laço for em Python iterando sobre:
 • string
 • arquivo
 • Django QuerySet
 • Baralho
                                       @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
                                          @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
                                          @ramalhoorg
(
 Interface? Em Python?
• Interface é um conceito essencial em OO
• Em Smalltalk: “protocolo”
     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.

         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.    @ramalhoorg
         DOI=10.1145/74877.74924 http://doi.acm.org/10.1145/74877.74924
(
 Interface? Em Python?
• Interface é um conceito essencial em OO
• Em Smalltalk: “protocolo”
     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.

        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.    @ramalhoorg
        DOI=10.1145/74877.74924 http://doi.acm.org/10.1145/74877.74924
)
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++
                                           @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.
                                             @ramalhoorg
Protocolo de sequência
 >>> t = Trem(4)
 >>> len(t)
 4
                       __len__
 >>> t[0]
 'vagao #1'
 >>> t[3]              __getitem__
 'vagao #4'
 >>> t[-1]
 'vagao #4'
 >>> for vagao in t:
 ...   print(vagao)
                       __getitem__
 vagao #1
 vagao #2
 vagao #3
 vagao #4



                                 @ramalhoorg
Protocolo
  de sequência
  • collections.Sequence
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) @ramalhoorg
Interface
Iterable

• Iterable provê um método
  __iter__
• O método __iter__ devolve
  uma instância de Iterator



                              @ramalhoorg
Iterator é...

• um padrão de projeto

                         Design Patterns
                         Gamma, Helm, Johnson & Vlissides
                         Addison-Wesley,
                         ISBN 0-201-63361-2




                                              @ramalhoorg
Head First
Design Patterns
Poster
O'Reilly,
ISBN 0-596-10214-3




                     @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
Poster
O'Reilly,
ISBN 0-596-10214-3




                     @ramalhoorg
Trem
                      class Trem(object):
                          def __init__(self, num_vagoes):
                              self.num_vagoes = num_vagoes
                          def __iter__(self):

 com                          return IteradorTrem(self.num_vagoes)

                      class IteradorTrem(object):


 iterator
                          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:
      iter(t)                     raise StopIteration()

                         •   for vagao in t:

>>> t = Trem(4)
>>> for vagao in t:
                             •   invoca iter(t)
...   print(vagao)
vagao #1
                                 •   devolve IteradorTrem
vagao #2
vagao #3                     •   invoca itrem.next() até que
vagao #4                         ele levante StopIteration @ramalhoorg
Em Python, um iterável é...
• Um objeto a partir do qual a função iter
  consegue obter um iterador.
• A chamada iter(x):        interface Iterable

 • 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            @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
                                               @ramalhoorg
Função               >>> def g123():


geradora
                     ...     yield 1
                     ...     yield 2
                     ...     yield 3
                     ...
                     >>> for i in g123(): print i
                     ...

• Quando invocada,
                     1
                     2
                     3
  devolve um         >>> g = g123()
                     >>> g
  objeto gerador     <generator object g123 at 0x10e385e10>

• O objeto gerador
                     >>> g.next()
                     1
                     >>> g.next()
  é um iterável      2
                     >>> g.next()
                     3
                     >>> g.next()
                     Traceback (most recent call last):
                       File "<stdin>", line 1, in <module>
                     StopIteration                @ramalhoorg
Trem c/ função geradora
                      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)
      iter(t)
                        •   for vagao in t:

>>> t = Trem(4)
>>> for vagao in t:
                            •   invoca iter(t)
...   print(vagao)
vagao #1
                                •   devolve gerador
vagao #2
vagao #3                    •   invoca gerador.next() até que
vagao #4                        ele levante StopIteration @ramalhoorg
class Trem(object):

Iterador        def __init__(self, num_vagoes):
                    self.num_vagoes = num_vagoes
                def __iter__(self):


clássico
                    return IteradorTrem(self.num_vagoes)

            class IteradorTrem(object):
                def __init__(self, num_vagoes):
12 linhas           self.atual = 0
                    self.ultimo_vagao = num_vagoes - 1
de código       def next(self):
                    if self.atual <= self.ultimo_vagao:
                        self.atual += 1
                        return 'vagao #%s' % (self.atual)
                    else:
                        raise StopIteration()

                        mesma funcionalidade!
Função           class Trem(object):
                     def __init__(self, num_vagoes):

geradora                 self.num_vagoes = num_vagoes
                     def __iter__(self):
                         for i in range(self.num_vagoes):
                             yield 'vagao #%s' % (i+1)
 3 linhas
List comprehension
List comprehensions          ●   Compreensão de lista ou abrangência
                             ●   Exemplo: usar todos os elementos:
•   Expressões que consomem L2 = [n*10 for n in L]
                           – iteráveis e


    produzem listas
     qualquer iterável
    resultado: uma lista

>>> 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]

                                                          @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}



                                           @ramalhoorg
Expressão
geradora             >>> g = (n for n in [1, 2, 3])
                     >>> for i in g: print i
                     ...
                     1
                     2
                     3

• Quando avaliada,   >>> g = (n for n in [1, 2, 3])
                     >>> g
  devolve um         <generator object <genexpr> at
                     0x109a4deb0>
  objeto gerador     >>> g.next()
                     1

• O objeto gerador   >>> g.next()
                     2
  é um iterável      >>> g.next()
                     3
                     >>> g.next()
                     Traceback (most recent call last):
                       File "<stdin>", line 1, in <module>
                     StopIteration

                                                 @ramalhoorg
Trem c/ expressão geradora
                      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))
      iter(t)
                           •   for vagao in t:

>>> t = Trem(4)
>>> for vagao in t:
                               •   invoca iter(t)
...   print(vagao)
vagao #1
                                   •   devolve gerador
vagao #2
vagao #3                       •   invoca gerador.next() até que
vagao #4                           ele levante StopIteration @ramalhoorg
Tipos iteráveis embutidos
  • basestring   • frozenset
   • str         • list
   • unicode     • set
  • dict         • tuple
  • file          • xrange
                               @ramalhoorg
Funções embutidas que
consomem iteráveis
• all       • max
• any       • min
• filter     • reduce
• iter      • sorted
• len       • sum
• map       • zip
                        @ramalhoorg
Construtores embutidos
que consomem e
produzem iteráveis
• dict        • reversed
• enumerate   • set
• frozenset   • tuple
• list
                           @ramalhoorg
Operações com iteráveis
                                       >>>   a, b, c = 'XYZ'
  • Desempacotamento                   >>>
                                       'X'
                                             a

     de tupla                          >>>   b
                                       'Y'

     • em atribuições                  >>>
                                       'Z'
                                       >>>
                                             c

                                             g = (n for n in [1, 2, 3])
     • em chamadas de funções          >>>
                                       >>>
                                             a, b, c = g
                                             a
>>> def soma(a, b):                    1
...     return a + b                   >>>  b
...                                    2
>>> soma(1, 2)                         >>>  c
3                                      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)
                                                               @ramalhoorg
7
Módulo itertools
• 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()...    @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


                                           @ramalhoorg
Funções geradoras como
co-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


                                            @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

                                          @ramalhoorg
Luciano Ramalho
                                      luciano@ramalho.org
                                              @ramalhoorg




oficina online:
Objetos Pythonicos
POO e padrões de projeto como devem ser em Python
      Pré-inscrição: pre-oopy.turing.com.br
Iteráveis, geradores e iteradores em Python

Weitere ähnliche Inhalte

Was ist angesagt?

Python e django na prática
Python e django na práticaPython e django na prática
Python e django na práticaRafael Cassau
 
Postgresql + Python = Power!
Postgresql + Python = Power!Postgresql + Python = Power!
Postgresql + Python = Power!Juliano Atanazio
 
Python - Guia de bolso
Python - Guia de bolsoPython - Guia de bolso
Python - Guia de bolsoJean Lopes
 
Python: programação divertida novamente
Python: programação divertida novamentePython: programação divertida novamente
Python: programação divertida novamenteRodrigo Amaral
 
Desenvolvimento iOS - Aula 1
Desenvolvimento iOS - Aula 1Desenvolvimento iOS - Aula 1
Desenvolvimento iOS - Aula 1Saulo Arruda
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsHelder da Rocha
 
2016/01/27 - Aprendendo a programar com Python
2016/01/27 - Aprendendo a programar com Python2016/01/27 - Aprendendo a programar com Python
2016/01/27 - Aprendendo a programar com PythonJardel Weyrich
 
Curso java 06 - mais construtores, interfaces e polimorfismo
Curso java   06 - mais construtores, interfaces e polimorfismoCurso java   06 - mais construtores, interfaces e polimorfismo
Curso java 06 - mais construtores, interfaces e polimorfismoMaurício Linhares
 
Palestra python
Palestra pythonPalestra python
Palestra pythonRony Cruch
 
Curso java 01 - molhando os pés com java
Curso java   01 - molhando os pés com javaCurso java   01 - molhando os pés com java
Curso java 01 - molhando os pés com javaMaurício Linhares
 
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...Danilo J. S. Bellini
 

Was ist angesagt? (19)

Python e django na prática
Python e django na práticaPython e django na prática
Python e django na prática
 
Curso de Python e Django
Curso de Python e DjangoCurso de Python e Django
Curso de Python e Django
 
Python 02
Python 02Python 02
Python 02
 
Python 01
Python 01Python 01
Python 01
 
Postgresql + Python = Power!
Postgresql + Python = Power!Postgresql + Python = Power!
Postgresql + Python = Power!
 
Programando com Python
Programando com PythonProgramando com Python
Programando com Python
 
Python 03
Python 03Python 03
Python 03
 
Python - Guia de bolso
Python - Guia de bolsoPython - Guia de bolso
Python - Guia de bolso
 
Python: programação divertida novamente
Python: programação divertida novamentePython: programação divertida novamente
Python: programação divertida novamente
 
Aprendendo ruby
Aprendendo rubyAprendendo ruby
Aprendendo ruby
 
Desenvolvimento iOS - Aula 1
Desenvolvimento iOS - Aula 1Desenvolvimento iOS - Aula 1
Desenvolvimento iOS - Aula 1
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e Streams
 
2016/01/27 - Aprendendo a programar com Python
2016/01/27 - Aprendendo a programar com Python2016/01/27 - Aprendendo a programar com Python
2016/01/27 - Aprendendo a programar com Python
 
Curso java 06 - mais construtores, interfaces e polimorfismo
Curso java   06 - mais construtores, interfaces e polimorfismoCurso java   06 - mais construtores, interfaces e polimorfismo
Curso java 06 - mais construtores, interfaces e polimorfismo
 
Palestra python
Palestra pythonPalestra python
Palestra python
 
Introducao Google GO
Introducao Google GOIntroducao Google GO
Introducao Google GO
 
Java para iniciantes
Java para iniciantesJava para iniciantes
Java para iniciantes
 
Curso java 01 - molhando os pés com java
Curso java   01 - molhando os pés com javaCurso java   01 - molhando os pés com java
Curso java 01 - molhando os pés com java
 
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
 

Ähnlich wie Iteráveis, geradores e iteradores em Python

Introdução a linguagem Python
Introdução a linguagem PythonIntrodução a linguagem Python
Introdução a linguagem PythonLuciano Ramalho
 
Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Luciano Ramalho
 
Introdução à Linguagem de programação Python
Introdução à Linguagem de programação PythonIntrodução à Linguagem de programação Python
Introdução à Linguagem de programação Pythondmmartins
 
POO-FundamentosPOO.pdf
POO-FundamentosPOO.pdfPOO-FundamentosPOO.pdf
POO-FundamentosPOO.pdfFausto Ayres
 
Classe integer-float-byte-short-long-double
Classe integer-float-byte-short-long-doubleClasse integer-float-byte-short-long-double
Classe integer-float-byte-short-long-doublePAULO Moreira
 
55 New Things in Java 7 - Brazil
55 New Things in Java 7 - Brazil55 New Things in Java 7 - Brazil
55 New Things in Java 7 - BrazilStephen Chin
 
Javascript para CSharpers 2 - Functions
Javascript para CSharpers   2 - FunctionsJavascript para CSharpers   2 - Functions
Javascript para CSharpers 2 - FunctionsWesley Lemos
 
Orientação a Objetos com Python e UML - XIII FGSL
Orientação a Objetos com Python e UML - XIII FGSLOrientação a Objetos com Python e UML - XIII FGSL
Orientação a Objetos com Python e UML - XIII FGSLGeorge Mendonça
 
Threads 07: Sincronizadores
Threads 07: SincronizadoresThreads 07: Sincronizadores
Threads 07: SincronizadoresHelder da Rocha
 
Scala: unindo programação funcional e orientação a objetos
Scala: unindo programação funcional e orientação a objetosScala: unindo programação funcional e orientação a objetos
Scala: unindo programação funcional e orientação a objetosFelipe Hummel
 
Programação orientada a objetos - IV
Programação orientada a objetos - IVProgramação orientada a objetos - IV
Programação orientada a objetos - IVGabriel Faustino
 
Python 3.x - Ihh.. E agora ? Como faço ?
Python 3.x - Ihh.. E agora ? Como faço ?Python 3.x - Ihh.. E agora ? Como faço ?
Python 3.x - Ihh.. E agora ? Como faço ?Marcel Caraciolo
 
As Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoPaulo Morgado
 

Ähnlich wie Iteráveis, geradores e iteradores em Python (20)

M2ti - Python Brasil
M2ti - Python BrasilM2ti - Python Brasil
M2ti - Python Brasil
 
Python
PythonPython
Python
 
Introdução a linguagem Python
Introdução a linguagem PythonIntrodução a linguagem Python
Introdução a linguagem Python
 
Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011
 
Palestra2009
Palestra2009Palestra2009
Palestra2009
 
Threads 09: Paralelismo
Threads 09: ParalelismoThreads 09: Paralelismo
Threads 09: Paralelismo
 
Introdução à Linguagem de programação Python
Introdução à Linguagem de programação PythonIntrodução à Linguagem de programação Python
Introdução à Linguagem de programação Python
 
POO-FundamentosPOO.pdf
POO-FundamentosPOO.pdfPOO-FundamentosPOO.pdf
POO-FundamentosPOO.pdf
 
Classe integer-float-byte-short-long-double
Classe integer-float-byte-short-long-doubleClasse integer-float-byte-short-long-double
Classe integer-float-byte-short-long-double
 
55 New Things in Java 7 - Brazil
55 New Things in Java 7 - Brazil55 New Things in Java 7 - Brazil
55 New Things in Java 7 - Brazil
 
Javascript para CSharpers 2 - Functions
Javascript para CSharpers   2 - FunctionsJavascript para CSharpers   2 - Functions
Javascript para CSharpers 2 - Functions
 
Orientação a Objetos com Python e UML - XIII FGSL
Orientação a Objetos com Python e UML - XIII FGSLOrientação a Objetos com Python e UML - XIII FGSL
Orientação a Objetos com Python e UML - XIII FGSL
 
Threads 07: Sincronizadores
Threads 07: SincronizadoresThreads 07: Sincronizadores
Threads 07: Sincronizadores
 
Scala: unindo programação funcional e orientação a objetos
Scala: unindo programação funcional e orientação a objetosScala: unindo programação funcional e orientação a objetos
Scala: unindo programação funcional e orientação a objetos
 
Aula python
Aula pythonAula python
Aula python
 
Metaprogramming
Metaprogramming Metaprogramming
Metaprogramming
 
Programação orientada a objetos - IV
Programação orientada a objetos - IVProgramação orientada a objetos - IV
Programação orientada a objetos - IV
 
Python 3.x - Ihh.. E agora ? Como faço ?
Python 3.x - Ihh.. E agora ? Como faço ?Python 3.x - Ihh.. E agora ? Como faço ?
Python 3.x - Ihh.. E agora ? Como faço ?
 
As Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPonto
 
Meta-programacao em python
Meta-programacao em pythonMeta-programacao em python
Meta-programacao em python
 

Mehr von Luciano Ramalho

Encapsulamento com descritores
Encapsulamento com descritoresEncapsulamento com descritores
Encapsulamento com descritoresLuciano Ramalho
 
Arduino: hardware hacking & coding dojo
Arduino: hardware hacking & coding dojoArduino: hardware hacking & coding dojo
Arduino: hardware hacking & coding dojoLuciano Ramalho
 
Encapsulamento com Descritores em Python
Encapsulamento com Descritores em PythonEncapsulamento com Descritores em Python
Encapsulamento com Descritores em PythonLuciano Ramalho
 
OO em Python sem sotaque
OO em Python sem sotaqueOO em Python sem sotaque
OO em Python sem sotaqueLuciano Ramalho
 
Python, a arma secreta do Google
Python, a arma secreta do GooglePython, a arma secreta do Google
Python, a arma secreta do GoogleLuciano Ramalho
 
Alex Martelli's Python Design Patterns
Alex Martelli's Python Design PatternsAlex Martelli's Python Design Patterns
Alex Martelli's Python Design PatternsLuciano Ramalho
 
JavaScript agora é sério (TDC 2011)
JavaScript agora é sério (TDC 2011)JavaScript agora é sério (TDC 2011)
JavaScript agora é sério (TDC 2011)Luciano Ramalho
 
JavaScript agora é sério (FISL 2011)
JavaScript agora é sério (FISL 2011)JavaScript agora é sério (FISL 2011)
JavaScript agora é sério (FISL 2011)Luciano Ramalho
 
JavaScript: agora é sério
JavaScript: agora é sérioJavaScript: agora é sério
JavaScript: agora é sérioLuciano Ramalho
 
Porque bibliotecários usam bancos de dados esquisitos
Porque bibliotecários usam bancos de dados esquisitosPorque bibliotecários usam bancos de dados esquisitos
Porque bibliotecários usam bancos de dados esquisitosLuciano Ramalho
 

Mehr von Luciano Ramalho (20)

Wiki-wiki S/A
Wiki-wiki S/AWiki-wiki S/A
Wiki-wiki S/A
 
Mongodb: agregação
Mongodb: agregaçãoMongodb: agregação
Mongodb: agregação
 
Encapsulamento com descritores
Encapsulamento com descritoresEncapsulamento com descritores
Encapsulamento com descritores
 
Arduino: hardware hacking & coding dojo
Arduino: hardware hacking & coding dojoArduino: hardware hacking & coding dojo
Arduino: hardware hacking & coding dojo
 
Encapsulamento com Descritores em Python
Encapsulamento com Descritores em PythonEncapsulamento com Descritores em Python
Encapsulamento com Descritores em Python
 
Dojo com Processing
Dojo com ProcessingDojo com Processing
Dojo com Processing
 
Dojo com Arduino
Dojo com ArduinoDojo com Arduino
Dojo com Arduino
 
Open Library no Mongodb
Open Library no MongodbOpen Library no Mongodb
Open Library no Mongodb
 
OO em Python sem sotaque
OO em Python sem sotaqueOO em Python sem sotaque
OO em Python sem sotaque
 
Modelos ricos
Modelos ricosModelos ricos
Modelos ricos
 
Python, a arma secreta do Google
Python, a arma secreta do GooglePython, a arma secreta do Google
Python, a arma secreta do Google
 
Ensinando OO com Python
Ensinando OO com PythonEnsinando OO com Python
Ensinando OO com Python
 
Alex Martelli's Python Design Patterns
Alex Martelli's Python Design PatternsAlex Martelli's Python Design Patterns
Alex Martelli's Python Design Patterns
 
Dspace em 5 minutos
Dspace em 5 minutosDspace em 5 minutos
Dspace em 5 minutos
 
JavaScript agora é sério (TDC 2011)
JavaScript agora é sério (TDC 2011)JavaScript agora é sério (TDC 2011)
JavaScript agora é sério (TDC 2011)
 
JavaScript agora é sério (FISL 2011)
JavaScript agora é sério (FISL 2011)JavaScript agora é sério (FISL 2011)
JavaScript agora é sério (FISL 2011)
 
Wiki sa-v2
Wiki sa-v2Wiki sa-v2
Wiki sa-v2
 
JavaScript: agora é sério
JavaScript: agora é sérioJavaScript: agora é sério
JavaScript: agora é sério
 
Porque bibliotecários usam bancos de dados esquisitos
Porque bibliotecários usam bancos de dados esquisitosPorque bibliotecários usam bancos de dados esquisitos
Porque bibliotecários usam bancos de dados esquisitos
 
Binary divination
Binary divinationBinary divination
Binary divination
 

Iteráveis, geradores e iteradores em Python

  • 1. Luciano Ramalho luciano@ramalho.org @ramalhoorg Iteráveis, geradores & cia: a essência do Python
  • 2.
  • 3. 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 @ramalhoorg
  • 4.
  • 5.
  • 6. Exemplos • Laço for em Python iterando sobre: • string • arquivo • Django QuerySet • Baralho @ramalhoorg
  • 7. 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 @ramalhoorg
  • 8. 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 @ramalhoorg
  • 9. ( Interface? Em Python? • Interface é um conceito essencial em OO • Em Smalltalk: “protocolo” 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. 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. @ramalhoorg DOI=10.1145/74877.74924 http://doi.acm.org/10.1145/74877.74924
  • 10. ( Interface? Em Python? • Interface é um conceito essencial em OO • Em Smalltalk: “protocolo” 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. 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. @ramalhoorg DOI=10.1145/74877.74924 http://doi.acm.org/10.1145/74877.74924
  • 11. ) 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++ @ramalhoorg
  • 12. 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. @ramalhoorg
  • 13. Protocolo de sequência >>> t = Trem(4) >>> len(t) 4 __len__ >>> t[0] 'vagao #1' >>> t[3] __getitem__ 'vagao #4' >>> t[-1] 'vagao #4' >>> for vagao in t: ... print(vagao) __getitem__ vagao #1 vagao #2 vagao #3 vagao #4 @ramalhoorg
  • 14. Protocolo de sequência • collections.Sequence 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) @ramalhoorg
  • 15. Interface Iterable • Iterable provê um método __iter__ • O método __iter__ devolve uma instância de Iterator @ramalhoorg
  • 16. Iterator é... • um padrão de projeto Design Patterns Gamma, Helm, Johnson & Vlissides Addison-Wesley, ISBN 0-201-63361-2 @ramalhoorg
  • 18. 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 Poster O'Reilly, ISBN 0-596-10214-3 @ramalhoorg
  • 19. Trem class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): com return IteradorTrem(self.num_vagoes) class IteradorTrem(object): iterator 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: iter(t) raise StopIteration() • for vagao in t: >>> t = Trem(4) >>> for vagao in t: • invoca iter(t) ... print(vagao) vagao #1 • devolve IteradorTrem vagao #2 vagao #3 • invoca itrem.next() até que vagao #4 ele levante StopIteration @ramalhoorg
  • 20. Em Python, um iterável é... • Um objeto a partir do qual a função iter consegue obter um iterador. • A chamada iter(x): interface Iterable • 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 @ramalhoorg
  • 21. 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 @ramalhoorg
  • 22. Função >>> def g123(): geradora ... yield 1 ... yield 2 ... yield 3 ... >>> for i in g123(): print i ... • Quando invocada, 1 2 3 devolve um >>> g = g123() >>> g objeto gerador <generator object g123 at 0x10e385e10> • O objeto gerador >>> g.next() 1 >>> g.next() é um iterável 2 >>> g.next() 3 >>> g.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration @ramalhoorg
  • 23. Trem c/ função geradora 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) iter(t) • for vagao in t: >>> t = Trem(4) >>> for vagao in t: • invoca iter(t) ... print(vagao) vagao #1 • devolve gerador vagao #2 vagao #3 • invoca gerador.next() até que vagao #4 ele levante StopIteration @ramalhoorg
  • 24. class Trem(object): Iterador def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): clássico return IteradorTrem(self.num_vagoes) class IteradorTrem(object): def __init__(self, num_vagoes): 12 linhas self.atual = 0 self.ultimo_vagao = num_vagoes - 1 de código def next(self): if self.atual <= self.ultimo_vagao: self.atual += 1 return 'vagao #%s' % (self.atual) else: raise StopIteration() mesma funcionalidade! Função class Trem(object): def __init__(self, num_vagoes): geradora self.num_vagoes = num_vagoes def __iter__(self): for i in range(self.num_vagoes): yield 'vagao #%s' % (i+1) 3 linhas
  • 25. List comprehension List comprehensions ● Compreensão de lista ou abrangência ● Exemplo: usar todos os elementos: • Expressões que consomem L2 = [n*10 for n in L] – iteráveis e produzem listas qualquer iterável resultado: uma lista >>> 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] @ramalhoorg
  • 26. 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} @ramalhoorg
  • 27. Expressão geradora >>> g = (n for n in [1, 2, 3]) >>> for i in g: print i ... 1 2 3 • Quando avaliada, >>> g = (n for n in [1, 2, 3]) >>> g devolve um <generator object <genexpr> at 0x109a4deb0> objeto gerador >>> g.next() 1 • O objeto gerador >>> g.next() 2 é um iterável >>> g.next() 3 >>> g.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration @ramalhoorg
  • 28. Trem c/ expressão geradora 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)) iter(t) • for vagao in t: >>> t = Trem(4) >>> for vagao in t: • invoca iter(t) ... print(vagao) vagao #1 • devolve gerador vagao #2 vagao #3 • invoca gerador.next() até que vagao #4 ele levante StopIteration @ramalhoorg
  • 29. Tipos iteráveis embutidos • basestring • frozenset • str • list • unicode • set • dict • tuple • file • xrange @ramalhoorg
  • 30. Funções embutidas que consomem iteráveis • all • max • any • min • filter • reduce • iter • sorted • len • sum • map • zip @ramalhoorg
  • 31. Construtores embutidos que consomem e produzem iteráveis • dict • reversed • enumerate • set • frozenset • tuple • list @ramalhoorg
  • 32. Operações com iteráveis >>> a, b, c = 'XYZ' • Desempacotamento >>> 'X' a de tupla >>> b 'Y' • em atribuições >>> 'Z' >>> c g = (n for n in [1, 2, 3]) • em chamadas de funções >>> >>> a, b, c = g a >>> def soma(a, b): 1 ... return a + b >>> b ... 2 >>> soma(1, 2) >>> c 3 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) @ramalhoorg 7
  • 33. Módulo itertools • 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()... @ramalhoorg
  • 34. 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 @ramalhoorg
  • 35. Funções geradoras como co-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 @ramalhoorg
  • 36. 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 @ramalhoorg
  • 37. Luciano Ramalho luciano@ramalho.org @ramalhoorg oficina online: Objetos Pythonicos POO e padrões de projeto como devem ser em Python Pré-inscrição: pre-oopy.turing.com.br