Iteradores personalizados

Programação Orientada a Objetos Intermediária em Python

Jake Roach

Data Engineer

Iteradores

Classes que permitem percorrer uma coleção de objetos ou fluxo de dados e retornam um item por vez

  • Parecidos com list, tuple, mas funcionam diferente
  • Navegar, transformar, gerar
  • Iterados com for
  • Função next()

$$

Protocolo de iterador...

# Collection
chuck = NameIterator("Charles Carmicheal")
for letter in chuck:
    print(letter)
C
h
u
...
# Data stream
fun_game = DiceGame(rolls=3)
next(fun_game)  # ... and so on
4
Programação Orientada a Objetos Intermediária em Python

Protocolo de iterador

__iter__()

  • Retorna um iterador; aqui, uma referência a si mesmo
  • ... return self

$$

__next__()

  • Retorna o próximo valor da coleção ou do fluxo de dados
  • Onde ocorre iteração, transformação e geração

$$

Ambos __iter__() e __next__() devem ser definidos para uma classe ser um iterador!

Programação Orientada a Objetos Intermediária em Python

Iterador de exemplo

class CoinFlips:
    def __init__(self, number_of_flips):
        self.number_of_flips = number_of_flips  # Store the total number of flips
        self.counter = 0

    def __iter__(self):
        return self  # Return a reference of the iterator

    # Flip the next coin, return the output
    def __next__(self):
        if self.counter < self.number_of_flips:
            self.counter += 1
            return random.choice(["H", "T"])
Programação Orientada a Objetos Intermediária em Python

Usando um iterador de exemplo

three_flips = CoinFlips(3)

# Jogue a moeda três vezes
next(three_flips)
next(three_flips)
next(three_flips)
H
H
T
Programação Orientada a Objetos Intermediária em Python

Iterando por um iterador

three_flips = CoinFlips(3)

# Agora, tente iterar por cada elemento do iterador
for flip in three_flips:
    print(flip)
T
H
T
None
None
None
...
Programação Orientada a Objetos Intermediária em Python

StopIteration

...
    def __next__(self):
        # Only do this if the coin hasn't been flipped "number_of_flips" times
        if self.counter < self.number_of_flips:
            self.counter += 1
            return random.choice(["H", "T"])

        else:  # Otherwise, stop execution with StopIteration
            raise StopIteration
  • Sinaliza o fim da coleção/fluxo de dados
  • Evita loops infinitos
  • Fácil de tratar
Programação Orientada a Objetos Intermediária em Python

Iterando por um iterador

three_flips = CoinFlips(3)

# Agora, tente iterar por cada elemento do iterador
for flip in three_flips:
    print(flip)
H
T
H
Programação Orientada a Objetos Intermediária em Python

Tratando exceções StopIteration

while True:
    try:
        next(three_flips)  # Pull the next element of three_flips

    # Catch a stop iteration exception
    except StopIteration:
        print("Completed all coin flips!")
        break
H
H
H
Completed all coin flips!
Programação Orientada a Objetos Intermediária em Python

Vamos praticar!

Programação Orientada a Objetos Intermediária em Python

Preparing Video For Download...