15.12.2022 Views

Python Eficaz

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

it = read_visits('/tmp/my_numbers.txt')

percentages = normalize_copy(it)

print(percentages)

>>>

[11.538461538461538, 26.923076923076923, 61.53846153846154]

O problema com essa técnica é que a cópia do iterador de entrada pode ser muito

grande. Copiar o iterador pode causar uso excessivo de memória e o travamento

do programa. Uma forma de contornar o erro é aceitar uma função que retorne

um novo iterador a cada vez que for chamada.

def normalize_func(get_iter):

total = sum(get_iter()) # Novo iterador

result = []

for value in get_iter(): # Novo iterador

percent = 100 * value / total

result.append(percent)

return result

Para usar normalize_func, basta passar uma expressão lambda, que chama o

gerador e produz um novo iterador a cada chamada.

percentages = normalize_func(lambda: read_visits(path))

Embora funcione, ter de usar uma função lambda dessa maneira é bastante

desajeitado. A melhor maneira de obter o mesmo resultado é providenciar uma

nova classe de contenção que implementa o protocolo de iteração.

No Python, o protocolo de iteração é a maneira como os laços for e expressões

afins navegam pelo conteúdo de um tipo de dados contêiner. Quando o Python

vê um comando do tipo for x in foo, o que ele fará na verdade é chamar iter(foo).

A função nativa iter, por sua vez, chama o método especial foo.__iter__. O

método __iter__ retorna um objeto iterador (que por sua vez implementa o

método especial __next__ ). Depois, o laço for chama repetidamente a função

nativa next no objeto do iterador até que esteja exaurido (ou seja, todos os itens

foram lidos) e gera uma exceção StopIteration.

Parece complicado, mas em termos práticos podemos conseguir exatamente o

mesmo comportamento para as classes implementando o método __iter__ como

um gerador. No exemplo a seguir, definimos uma classe iterável do tipo

www.full-ebook.com

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!