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.

After: {'orange': 9, 'green': 12, 'blue': 20, 'red': 5}

Disponibilizar funções como log_missing torna as APIs fáceis de construir e

testar porque separam o comportamento determinístico dos efeitos colaterais.

Por exemplo, digamos que agora se queira o gancho do valor default passado

para a classe defaultdict para que se possa contar o número total de chaves não

encontradas. Uma maneira de se fazer isso é usar um closure que armazene seu

estado (stateful – consulte o Item 15: “Saiba como os closures interagem com os

escopos das variáveis” para mais informações). No exemplo a seguir, definimos

uma função auxiliar que usa um closure como esse como gancho de valor

default:

def increment_with_report(current, increments):

added_count = 0

def missing():

nonlocal added_count # Closure que guarda seu estado (stateful)

added_count += 1

return 0

result = defaultdict(missing, current)

for key, amount in increments:

result[key] += amount

return result, added_count

Essa função, quando executada, produz o resultado esperado (2), mesmo que

defaultdict não tenha a mínima ideia de que o gancho missing guarde seu estado.

Esse é um dos grandes benefícios de aceitar funções simples como interfaces. É

fácil adicionar funcionalidade mais tarde simplesmente escondendo algum

estado dentro de um closure.

result, count = increment_with_report(current, increments)

assert count == 2

O problema ao definir um closure para ganchos stateful é que é mais difícil de

ler que no exemplo da função sem estado (stateless). Outra maneira de abordar o

problema poderia ser a definição de uma pequena classe que encapsule o estado

www.full-ebook.com

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

Saved successfully!

Ooh no, something went wrong!