Geradores Python

Resumo : neste tutorial, você aprenderá sobre geradores Python e como usá-los para criar iteradores

Introdução aos geradores Python

Normalmente, o Python executa uma função regular de cima para baixo com base no modelo de execução até a conclusão.

Isso significa que o Python não pode pausar uma função regular no meio do caminho e então retomar a função depois disso. Por exemplo:

def greeting():
    print('Hi!')
    print('How are you?')
    print('Are you there?')Linguagem de código:  Python  ( python )

Quando Python executa a greeting()função, ele executa o código linha por linha, de cima para baixo.

Além disso, o Python não pode pausar a função na seguinte linha:

print('How are you?')Linguagem de código:  Python  ( python )

… e salta para outro código e retoma a execução daquela linha.

Para pausar uma função no meio e retomar de onde a função foi pausada, você usa a yieldinstrução.

Quando uma função contém pelo menos uma yieldinstrução, é uma função geradora .

Por definição, um gerador é uma função que contém pelo menos uma instrução de rendimento.

Quando você chama uma função geradora, ela retorna um novo objeto gerador. No entanto, ele não inicia a função.

Objetos geradores (ou geradores) implementam o protocolo iterador . Na verdade, os geradores são iteradores preguiçosos. Portanto, para executar uma função geradora, você chama a next()função integrada nela.

Um exemplo simples de gerador Python

Veja o exemplo a seguir:

def greeting():
    print('Hi!')
    yield 1
    print('How are you?')
    yield 2
    print('Are you there?')
    yield 3Linguagem de código:  Python  ( python )

Como a greeting()função contém as yieldinstruções, é uma função geradora.

A yieldinstrução é como uma returninstrução em uma função. No entanto, há uma grande diferença.

Quando Python encontra a yieldinstrução, ele retorna o valor especificado no arquivo yield. Além disso, pausa a execução da função.

Se você “chamar” a mesma função novamente, o Python continuará de onde a yieldinstrução anterior foi encontrada.

Quando você chama uma função geradora, ela retorna um objeto gerador. Por exemplo:

messenger = greeting()Linguagem de código:  Python  ( python )

O messengeré um objeto gerador, que também é um iterador .

Para realmente executar o corpo da greeting()função, você precisa usar a next()função integrada:

result = next(messenger)
print(result)Linguagem de código:  Python  ( python )

Quando a greeting()função é executada, ela mostra a primeira mensagem e retorna 1:

Hi!
1Linguagem de código:  Python  ( python )

Além disso, está pausado logo na primeira yieldinstrução. Se você “chamar” a greeting()função novamente, ela retomará a execução da última yieldinstrução:

result = next(messenger)
print(result)Linguagem de código:  Python  ( python )

Saída:

How are you?
2Linguagem de código:  Python  ( python )

E você pode chamá-lo novamente:

result = next(messenger)
print(result) Linguagem de código:  Python  ( python )

Saída:

Are you there?
3Linguagem de código:  Python  ( python )

No entanto, se você executar o gerador mais uma vez, ele gerará a exceção StopIteration porque é um iterador :

next(messenger)Linguagem de código:  Python  ( python )

Erro:

StopIteration      Linguagem de código:  Python  ( python )

Usando geradores Python para criar iteradores

O exemplo a seguir define um iterador que retorna um número quadrado de um número inteiro.

class Squares:
    def __init__(self, length):
        self.length = length
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        result = self.current ** 2

        self.current += 1

        if self.current > self.length:
            raise StopIteration

        return resultLinguagem de código:  Python  ( python )

E você pode usar o Squaresiterador para gerar os números quadrados dos primeiros 5 inteiros de 0 a 5:

length = 5
square = Squares(length)
for s in square:
    print(s)Linguagem de código:  Python  ( python )

Este código funciona como esperávamos. Mas há um problema: há muitos clichês.

E como você pode imaginar, você usa uma função geradora para construir esse iterador.

O seguinte reescreve o Squaresiterador como uma função geradora:

def squares(length):
    for n in range(length):
        yield n ** 2Linguagem de código:  Python  ( python )

Como você pode ver, é muito mais curto e expressivo. O uso da squaresfunção geradora é semelhante ao iterador acima:

length = 5
square = squares(length)
for s in square:
    print(s)Linguagem de código:  Python  ( python )

Resumo

  • Geradores Python são funções que contêm pelo menos uma instrução de rendimento.
  • Uma função geradora retorna um objeto gerador.
  • Um objeto gerador é um iterador. Portanto, ele se esgota quando não há mais nenhum item para devolver.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *