O que são funções geradoras? (Ou como funciona o SimPy) Parte I
O comando yield
é quem, como você já deve ter notado, dá o ritmo do seu modelo em SimPy. Para melhor compreender como funciona um programa em SimPy, precisamos entender, além do próprio comando yield,
outro conceito fundamental em programação: as funções geradoras.
Começaremos pelo conceito de Iterador.
Iterador
Na programação orientada ao objeto, iteradores são métodos que permitem ao programa observar os valores dentro de um dado objeto.
Quando você percorre uma lista com o comando for
por exemplo, está intrinsecamente utilizando um iterador:
No exemplo, lista
é um objeto e o comando for
é um iterador que permite vasculhar cada elemento dentro da lista, retornando sempre o próximo elemento do objeto.
Funções geradoras
Elas existem e (estão entre nós desde o início dos tempos...)
Uma função geradora é uma classe especial de função que tem como característica retornar, cada vez que é chamada, valores em sequência. O que torna uma função qualquer em Python uma função geradora é a presença do comando yield
em seu corpo.
O comando yield
funciona, na primeira vez em que a função é chamada, algo semelhante a um return
mas com um superpoder: quando a função é chamada novamente, a execução começa a partir da linha seguinte ao yield
.
Por exemplo, podemos imprimir os mesmo números da lista anterior, chamando 3 vezes a função seqNum(),
definida a seguir:
Note que a função geradora seqNum
é um objeto, e que o loop for
permite acessar os elementos retornados por cada yield
.
À primeira fez que o loop for
chamou a função seqNum()
o código foi executado até a linha do yield n,
que retorna o valor 10
(afinal, n=10 neste momento).
Na segunda vez que o loop for
chama a função, ela não recomeça da primeira linha, de fato, ela é executada a partir da linha seguinte ao comando yield
(linha número 5 do código anterior) e retorna o valor 20
, pois n foi incrementado nesta segunda passagem.
Na terceira chamada à função, a execução retoma a partir da linha seguinte ao segundo yield
e o próximo valor de n será o anterior incrementado de 10.
Uma função geradora é, de fato, um iterador e você normalmente vai utilizá-la dentro de algum loop for
como no caso anterior. Outra possibilidade é você chamá-la diretamente pelo comando next
do Python, como será visto no próximo exemplo.
Exemplo:
Que tal uma função que nos diga a posição atual de um Zumbi que só pode andar uma casa por fez no plano xy? A função geradora a seguir acompanha o andar cambaleante do zumbi:
Diferentemente do caso anterior, criamos um zumbi a partir da linha:
Cada novo passo do pobre infeliz é obtido pelo comando:
O bacana, no caso, é que podemos criar 2 zumbis passeando pela relva:
Na seção a seguir discutiremos o papel da função geradora em um modelo de simulação. Por ora, sugerimos as seguintes fontes de consulta caso você procure um maior aprofundamento sobre o yield
e as funções geradoras:
Uma boa explicação na StackOverflow: What does the yield keyword do?
Last updated