Skip to content

Corrige alguns typos e outras coisas #91

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions capitulos/cap01.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ as implementações de `+__len__+` e `+__getitem__+` podem delegar todo o trabal
Como foi implementado até aqui, um `FrenchDeck` não pode ser embaralhado,
porque as cartas e suas posições não podem ser alteradas,
exceto violando o encapsulamento e manipulando o atributo `_cards` diretamente.
Em <<ifaces_prot_abc>> vamos corrigir isso acrescentando um método `+__setitem__+`
No <<ifaces_prot_abc>> vamos corrigir isso acrescentando um método `+__setitem__+`
de uma linha. Você consegue imaginar como ele seria implementado?
=====================================================================

Expand Down Expand Up @@ -580,7 +580,7 @@ O <<operator_overloading>> explica em detalhes os operadores reversos e a atribu
=== Por que len não é um método?

Em 2013, fiz((("Python Data Model", "making len work with custom objects")))((("&#x005F;&#x005F;len&#x005F;&#x005F;"))) essa pergunta a Raymond Hettinger, um dos desenvolvedores principais do Python, e o núcleo de sua resposta era uma citação do https://fpy.li/1-8["The Zen of Python" (_O Zen do Python_)] (EN): "a praticidade vence a pureza."
Em <<how_special_used>>, descrevi como `len(x)` roda muito rápido quando `x` é uma instância de um tipo embutido.
Na <<how_special_used>>, descrevi como `len(x)` roda muito rápido quando `x` é uma instância de um tipo embutido.
Nenhum método é chamado para os objetos embutidos do CPython: o tamanho é simplesmente lido de um campo em uma struct C.
Obter o número de itens em uma coleção é uma operação comum, e precisa funcionar de forma eficiente para tipos tão básicos e diferentes como `str`, `list`, `memoryview`, e assim por diante.

Expand Down
2 changes: 1 addition & 1 deletion capitulos/cap06.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ Se `a == b` é verdade, e nenhum dos dois objetos pode mudar, eles podem perfeit
Em programação funcional "pura", todos os dados são imutáveis: concatenar algo a uma coleção, na verdade, cria uma nova coleção.
Elixir é uma linguagem funcional prática e fácil de aprender, na qual todos os tipos nativos são imutáveis, incluindo as listas.

Python, por outro lado, não é uma linguagem funcional, menos uma ainda uma linguagem pura. Instâncias de classes definidas pelo usuário são mutáveis por default em Python -- como na maioria das linguagens orientadas a objetos. Ao criar seus próprios objetos, você tem que tomar o cuidado adicional de torná-los imutáveis, se este for um requisito. Cada atributo do objeto precisa ser também imutável, senão você termina criando algo como uma tupla: imutável quanto ao ID do objeto, mas seu valor pode mudar se a tupla contiver um objeto mutável.
Python, por outro lado, não é uma linguagem funcional, menos ainda uma linguagem pura. Instâncias de classes definidas pelo usuário são mutáveis por default em Python -- como na maioria das linguagens orientadas a objetos. Ao criar seus próprios objetos, você tem que tomar o cuidado adicional de torná-los imutáveis, se este for um requisito. Cada atributo do objeto precisa ser também imutável, senão você termina criando algo como uma tupla: imutável quanto ao ID do objeto, mas seu valor pode mudar se a tupla contiver um objeto mutável.

Objetos mutáveis também são a razão pela qual programar com threads é tão difícil: threads modificando objetos sem uma sincronização apropriada podem corromper dados. Sincronização excessiva, por outro lado, causa deadlocks.
A linguagem e a plataforma Erlang -- que inclui Elixir -- foi projetada para maximizar o tempo de execução em aplicações distribuídas de alta concorrência, tais como aplicações de controle de telecomunicações. Naturalmente, eles escolheram tornar os dados imutáveis por default.
Expand Down
2 changes: 1 addition & 1 deletion capitulos/cap08.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ birds.py:16: error: "Bird" has no attribute "quack"
Found 1 error in 1 file (checked 1 source file)
----

Mas o Mypy não vê qualquer problema com _daffy.py_ em si: as três chamadas de função estão OK.
Mas o Python não vê qualquer problema com _daffy.py_ em si: as três chamadas de função estão OK.

Agora, rodando _daffy.py_, o resultado é o seguinte:

Expand Down
2 changes: 1 addition & 1 deletion capitulos/cap15.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ A função `typing.get_type_hints` consegue resolver muitas dicas de tipo, inclu
{'text': <class 'str'>, 'max_len': <class 'int'>, 'return': <class 'str'>}
----

A chamada a `get_type_hints` nos dá os tipos resis—mesmo em alguns casos onde a dica de tipo original foi escrita como uma string.
A chamada a `get_type_hints` nos dá os tipos reais — mesmo em alguns casos onde a dica de tipo original foi escrita como uma string.
Essa é a maneira recomendada de ler dicas de tipo durante a execução.

O comportamento prescrito na PEP 563 estava previsto para se tornar o default no Python
Expand Down
14 changes: 7 additions & 7 deletions capitulos/cap16.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pela imposição de algumas limitações:
* Não é permitido criar novos operadores, apenas sobrecarregar os existentes.
* Alguns poucos operadores não podem ser sobrecarregados: `is`, `and`, `or` e `not` (mas os operadores `==`, `&`, `|`, e `~` podem).

No <<user_defined_sequences>>, na classe `Vector`, já apresentamos um operador infixo: `==`, suportado pelo método `+__eq__+`. Nesse capítulo, vamos melhorar a implementação de `+__eq__+` para lidar melhor com operandos de outros tipos além de `Vector`. Entretanto, os operadores de comparação cheia (`==`, `!=`, `>`, `<`, `>=`, `<=`) são casos especiais de sobrecarga de operadores, então começaremos sobrecarregando quatro operadores aritméticos em `Vector`: os operadores unários `-` e `+`, seguido pelos infixos `+` e `*`.
No <<user_defined_sequences>>, na classe `Vector`, já apresentamos um operador infixo: `==`, suportado pelo método `+__eq__+`. Nesse capítulo, vamos melhorar a implementação de `+__eq__+` para lidar melhor com operandos de outros tipos além de `Vector`. Entretanto, os operadores de comparação cheia (`==`, `!=`, `>`, `<`, `>=`, `<=`) são casos especiais de sobrecarga de operadores, então começaremos sobrecarregando quatro operadores aritméticos em `Vector`: os operadores unários `-` e `+++`, seguido pelos infixos `+++` e `*`.

Vamos começar pelo tópico mais fácil: operadores unários.

Expand Down Expand Up @@ -148,7 +148,7 @@ include::code/16-op-overloading/unary_plus_decimal.py[tags=UNARY_PLUS_DECIMAL]

O fato é que cada ocorrência da expressão `+one_third` produz uma nova instância de `Decimal` a partir do valor de `one_third`, mas usando a precisão do contexto aritmético atual.

Podemos encontrar o segundo caso onde `x != +x` na https://docs.python.org/pt-br/3/library/collections.html#collections.Counter[documentação] de `collections.Counter`. A classe `Counter` implementa vários operadores aritméticos, incluindo o `+` infixo, para somar a contagem de duas instâncias de `Counter`. Entretanto, por razões práticas, a adição em `Counter` descarta do resultado qualquer item com contagem negativa ou zero. E o prefixo `+` é um atalho para somar um `Counter` vazio, e portanto produz um novo `Counter`, preservando apenas as contagens maiores que zero. Veja o <<ex_unary_plus_counter>>.
Podemos encontrar o segundo caso onde `x != +x` na https://docs.python.org/pt-br/3/library/collections.html#collections.Counter[documentação] de `collections.Counter`. A classe `Counter` implementa vários operadores aritméticos, incluindo o `+` infixo, para somar a contagem de duas instâncias de `Counter`. Entretanto, por razões práticas, a adição em `Counter` descarta do resultado qualquer item com contagem negativa ou zero. E o prefixo `+++` é um atalho para somar um `Counter` vazio, e portanto produz um novo `Counter`, preservando apenas as contagens maiores que zero. Veja o <<ex_unary_plus_counter>>.

[[ex_unary_plus_counter]]
.O + unário produz um novo `Counter`sem as contagens negativas ou zero
Expand Down Expand Up @@ -177,8 +177,8 @@ Agora voltamos à nossa programação normal.((("", startref="OOunary16")))(((""
=== Sobrecarregando + para adição de Vector

A((("operator overloading", "overloading &#x002B; for vector addition", id="OOplus16")))((("mathematical vector operations")))((("&#x002B; operator", id="Plusover16")))((("vectors", "overloading &#x002B; for vector addition", id="Voverload16"))) classe `Vector` é um tipo sequência,
e a seção https://docs.python.org/pt-br/3/reference/datamodel.html#emulating-container-types["3.3.7. Emulando de tipos contêineres"] do capítulo "Modelo de Dados", na documentação oficial do Python, diz que sequências devem suportar o operador `+` para concatenação e o `+*+` para repetição.
Entretanto, aqui vamos implementar `+` e `+*+` como operações matemáticas de vetores, algo um pouco mais complicado mas mais significativo para um tipo `Vector`.
e a seção https://docs.python.org/pt-br/3/reference/datamodel.html#emulating-container-types["3.3.7. Emulando de tipos contêineres"] do capítulo "Modelo de Dados", na documentação oficial do Python, diz que sequências devem suportar o operador `+++` para concatenação e o `+*+` para repetição.
Entretanto, aqui vamos implementar `+++` e `+*+` como operações matemáticas de vetores, algo um pouco mais complicado mas mais significativo para um tipo `Vector`.

[TIP]
====
Expand Down Expand Up @@ -255,7 +255,7 @@ Vector([4.0, 6.0, 5.0])
----
====

Os dois usos de `+` no <<ex_vector_add_demo_mixed_ok>> funcionam porque `+__add__+` usa
Os dois usos de `+++` no <<ex_vector_add_demo_mixed_ok>> funcionam porque `+__add__+` usa
`zip_longest(…)`, capaz de consumir qualquer iterável, e a expressão geradora que cria um novo `Vector` simplemente efetua a operação `a + b` com os pares produzidos por `zip_longest(…)`, então um iterável que produza quaisquer itens numéricos servirá.

Entretanto, se trocarmos a ordem dos operandos (no <<ex_vector_add_demo_mixed_fail>>), a soma de tipos diferentes falha.
Expand Down Expand Up @@ -647,7 +647,7 @@ class Vector:
all(a == b for a, b in zip(self, other)))
----

Eaae método produz os resultados do <<eq_initial_demo>>.
Esse método produz os resultados do <<eq_initial_demo>>.

[[eq_initial_demo]]
.Comparando um `Vector` a um `Vector`, a um `Vector2d`, e a uma `tuple`
Expand Down Expand Up @@ -859,7 +859,7 @@ include::code/16-op-overloading/bingoaddable.py[tags=ADDABLE_BINGO_IADD_DEMO]
<5> Durante todo esse exemplo, `globe` sempre se refere ao mesmo objeto que `globe_orig`.
<6> Tentar adicionar um não-iterável a uma `AddableBingoCage` falha com uma mensagem de erro apropriada.

Observe que o operador `+=` é mais liberal que `+` quanto ao segundo operando. Com `+`, queremos que ambos os operandos sejam do mesmo tipo (nesse caso, `AddableBingoCage`), pois se aceitássemos tipos diferentes, isso poderia causar confusão quanto ao tipo do resultado. Com o `+=`, a situação é mais clara: o objeto à esquerda do operador é atualizado no mesmo lugar, então não há dúvida quanto ao tipo do resultado.
Observe que o operador `++=+` é mais liberal que `+++` quanto ao segundo operando. Com `+++`, queremos que ambos os operandos sejam do mesmo tipo (nesse caso, `AddableBingoCage`), pois se aceitássemos tipos diferentes, isso poderia causar confusão quanto ao tipo do resultado. Com o `++=+`, a situação é mais clara: o objeto à esquerda do operador é atualizado no mesmo lugar, então não há dúvida quanto ao tipo do resultado.

[TIP]
====
Expand Down
2 changes: 1 addition & 1 deletion capitulos/cap17.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ Por isso a próxima seção trata de várias funções geradoras prontas para us
// Perhaps you know all the functions mentioned in this section, but some of them are underused, so a quick overview may be good to recall what's already available.
// ====

A((("generators", "generator functions in Python standard library", id="Ggenfunc17"))) biblioteca padrão oferece muitas geradoras, desde objetos de arquivo de texto forncendo iteração linha por linha até a incrível função pass:[<a href="https://fpy.li/17-12"><code>os.walk</code></a>], que produz nomes de arquivos enquanto cruza uma árvore de diretórios, tornando buscas recursivas no sistema de arquivos tão simples quanto um loop `for`.
A((("generators", "generator functions in Python standard library", id="Ggenfunc17"))) biblioteca padrão oferece muitas geradoras, desde objetos de arquivo de texto fornecendo iteração linha por linha até a incrível função pass:[<a href="https://fpy.li/17-12"><code>os.walk</code></a>], que produz nomes de arquivos enquanto cruza uma árvore de diretórios, tornando buscas recursivas no sistema de arquivos tão simples quanto um loop `for`.

A função geradora `os.walk` é impressionante, mas nesta seção quero me concentrar em funções genéricas que recebem iteráveis arbitrários como argumento e devolvem geradores que produzem itens selecionados, calculados ou reordenados. Nas tabelas a seguir, resumi duas dúzias delas, algumas embutidas, outras dos módulos `itertools` e `functools`. Por conveniência, elas estão agrupadas por sua funcionalidade de alto nível, independente de onde são definidas.

Expand Down
2 changes: 1 addition & 1 deletion capitulos/cap19.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ Mas chega de conceitos por agora. Vamos ver algum código.((("", startref="CMcon
=== Um "Olá mundo" concorrente

Durante((("concurrency models", "Hello World example", id="CMhello19"))) uma discussão sobre threads e sobre como evitar a GIL, o contribuidor do Python Michele Simionato https://fpy.li/19-10[postou um exemplo] que é praticamente um "Olá Mundo" concorrente:
o programa mais simples possível mostrando como o Python pode "mascar chiclete e subir a escada ao mesmo tempo".
o programa mais simples possível mostrando como o Python pode "assobiar e chupar cana ao mesmo tempo".

O programa de Simionato usa `multiprocessing`,
mas eu o adaptei para apresentar também `threading` e `asyncio`.
Expand Down
2 changes: 1 addition & 1 deletion capitulos/cap21.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ include::code/21-async/mojifinder/tcp_mojifinder.py[tags=TCP_MOJIFINDER_MAIN]
<3> `host` e `port` são o segundo e o terceiro argumentos de `start_server`. Veja a assinatura completa na https://docs.python.org/pt-br/3/library/asyncio-stream.html#asyncio.start_server[documentação do `asyncio`].
<4> Este `cast` é necessário porque o _typeshed_ tem uma dica de tipo desatualizada para a propriedade `sockets` da classe `Server`—isso em maio de 2021. Veja https://fpy.li/21-36[Issue #5535 no _typeshed_].footnote:[O issue #5535 está fechado desde outubro de 2021, mas o Mypy não lançou uma nova versão desde então, daí o erro permanece.]
<5> Mostra o endereço e a porta do primeiro _socket_ do servidor.
<6> Apesar de `start_server` já ter iniciado o servidor como uma tarefa concorrente, preciso usar o `await` no método `server_forever`, para que meu `supervisor` seja suspenso aqui.
<6> Apesar de `start_server` já ter iniciado o servidor como uma tarefa concorrente, preciso usar o `await` no método `serve_forever`, para que meu `supervisor` seja suspenso aqui.
Sem essa linha, o `supervisor` retornaria imediatamente, encerrando o loop iniciado com `asyncio.run(supervisor(…))`, e fechando o programa. A
https://docs.python.org/pt-br/3/library/asyncio-eventloop.html#asyncio.Server.serve_forever[documentação de `Server.serve_forever`] diz: "Este método pode ser chamado se o servidor já estiver aceitando conexões."
<7> Constrói o índice invertido.footnote:[O revisor técnico Leonardo Rochael apontou que a construção do índice poderia ser delegada a outra thread, usando `loop.run_with_executor()` na corrotina `supervisor`. Dessa forma o servidor estaria pronto para receber requisições imediatamente, enquanto o índice é construído. Isso é verdade, mas como consultar o índice é a única coisa que esse servidor faz, isso não seria uma grande vantagem nesse exemplo.]
Expand Down
2 changes: 1 addition & 1 deletion capitulos/cap22.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ Revise a <<slots_section>> para recordar esse tópico.

Essas cinco funções embutidas executam leitura, escrita e introspecção de atributos de objetos:

`dir([object])`:: Lista((("dir([object]) function")))((("functions", "dir([object]) function"))) a maioria dis atributos de um objeto. A https://docs.python.org/pt-br/3/library/functions.html#dir[documentação oficial] diz que o objetivo de `dir` é o uso interativo, então ele não fornece uma lista completa de atributos, mas um conjunto de nomes "interessantes". `dir` pode inspecionar objetos implementados com ou sem um `+__dict__+`. O próprio atributo `+__dict__+` não é exibido por `dir`, mas as chaves de `+__dict__+` são listadas. Vários atributos especiais de classes, tais como
`dir([object])`:: Lista((("dir([object]) function")))((("functions", "dir([object]) function"))) a maioria dos atributos de um objeto. A https://docs.python.org/pt-br/3/library/functions.html#dir[documentação oficial] diz que o objetivo de `dir` é o uso interativo, então ele não fornece uma lista completa de atributos, mas um conjunto de nomes "interessantes". `dir` pode inspecionar objetos implementados com ou sem um `+__dict__+`. O próprio atributo `+__dict__+` não é exibido por `dir`, mas as chaves de `+__dict__+` são listadas. Vários atributos especiais de classes, tais como
`+__mro__+`, `+__bases__+` e `+__name__+`, também não são exibidos por `dir`. Você pode personalziar a saída de `dir` implementando o método especial `+__dir__+`, como vimos no <<ex_explore0>>. Se o argumento opcional `object` não for passado, `dir` lista os nomes no escopo corrente.

`getattr(object, name[, default])`:: Devolve((("functions", "getattr(object, name[, default]) function")))((("getattr(object, name[, default]) function"))) o atributo do `object` identificado pela string `name`. O principal caso de uso é obter atributos (ou métodos) cujos nomes não sabemos de antemão. Essa função pode recuperar um atributo da classe do objeto ou de uma superclasse. Se tal atributo não existir, `getattr` gera uma `AttributeError` ou devolve o valor `default`, se ele for passado.
Expand Down