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 yield
instrução.
Quando uma função contém pelo menos uma yield
instruçã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 3
Linguagem de código: Python ( python )
Como a greeting()
função contém as yield
instruções, é uma função geradora.
A yield
instrução é como uma return
instrução em uma função. No entanto, há uma grande diferença.
Quando Python encontra a yield
instruçã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 yield
instruçã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!
1
Linguagem de código: Python ( python )
Além disso, está pausado logo na primeira yield
instrução. Se você “chamar” a greeting()
função novamente, ela retomará a execução da última yield
instrução:
result = next(messenger)
print(result)
Linguagem de código: Python ( python )
Saída:
How are you?
2
Linguagem 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?
3
Linguagem 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 result
Linguagem de código: Python ( python )
E você pode usar o Squares
iterador 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 Squares
iterador como uma função geradora:
def squares(length):
for n in range(length):
yield n ** 2
Linguagem de código: Python ( python )
Como você pode ver, é muito mais curto e expressivo. O uso da squares
funçã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.