logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog


Tutorial informal de Python, parte 4
>>> # Mais uma parte do nosso tutorial informal. Hoje vamos
>>> # começar entendendo o que são iterators e suas aplicações
>>> # Existem duas formas básicas para gerar uma sequência para
>>> # ser enumerada em python. Primeiro temos o nosso já conhecido
>>> # range:
>>> for x in range(10):
...   print x,
...   
0 1 2 3 4 5 6 7 8 9
>>> # E temos o xrange:
>>> for x in xrange(10):
...   print x,
...   
 0 1 2 3 4 5 6 7 8 9
>>> # apesar do efeito ser o mesmo e o protótipo das duas funções
>>> # serem iguais, existe uma diferença grande na implementação:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> xrange(10)
xrange(10)
>>> # enquanto o range gera uma lista (ou seja, aloca todos os números), o xrange
>>> # retorna um objeto xrange que gera o número quando ele é solicitado. Isso pode
>>> # reduzir o consumo de memória e ser bastante eficiente caso você não percorra
>>> # todos os itens. Agora vamos ver por que eles são compatíveis.
>>> # Como já vimos antes, todos os métodos e propriedades que começam e terminam
>>> # com dois underlines (como o __dict__ que já vimos) são métodos que tem algum
>>> # significado especial para o interpretador Python.
>>> # Um desses métodos é o __iter__, que retorna um objeto iterator:
>>> l
xrange(10)
>>> i = l.__iter__()
>>> i
<rangeiterator object at 0x00ACA818>
>>> dir(i)
['__class__', '__delattr__', '__doc__', '__getattribute__', 
'__hash__', '__init__', '__iter__', '__length_hint__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 
'next']
>>> # o método que nos interessa é o next. Todo loop em Python é o equivalente a:
>>> i = l.__iter__()
>>> while 1:
...   try:
...     x = i.next()
...   except StopIteration:
...     break # passamos do último item
...   print x,
...   
0 1 2 3 4 5 6 7 8 9
>>> 
>>> # Como Python usa duck typing (lembra? Se parece um pato e anda como um pato,
>>> # é um pato), não é necessário que o iterator implemente uma interface
>>> # especial. Tendo o método next() e disparando a exceção StopIteration quando
>>> # os itens acabarem, tudo certo.
>>> 
>>> # Outra coisa que pode ser feita, é usar o iterator de uma classe nativa
>>> # para suportar iteração no seu objeto. Exemplo:
>>> class MyList:
...   def __init__(self):
...     self.l = []
...   def __iter__(self):
...     return self.l.__iter__()
...   def Append(self, x):
...     self.l.append(x)
...     
>>> l = MyList()
>>> l.Append('a')
>>> l.Append('b')
>>> l.Append('c')
>>> for x in l:
...   print x
...   
a
b
c
>>> # Resumindo: para suportar iteração seu objeto só precisa ter um método __iter__
>>> # que retorne um objeto que tenha um método next e que dispare StopIteration quando acabar

Em 17/12/2007 20:31, por Rodrigo Strauss


  
 
 
Comentários
rebarba rebarba
  ::::