You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -686,10 +686,13 @@ O <<ch_op_overload>> explica em detalhes os operadores reversos e a atribuição
686
686
687
687
=== Por que len não é um método?
688
688
689
-
Em 2013, fiz((("Python Data Model", "making len work with custom objects")))((("__len__"))) essa pergunta a Raymond Hettinger, um dos desenvolvedores principais de Python, e o núcleo de sua resposta era uma citação do https://fpy.li/1-8["The Zen of Python" (_O Zen de Python_)] (EN): "a praticidade vence a pureza."
690
-
Em <<how_special_used>>, descrevi como `len(x)` roda muito rápido quando `x` é uma instância de um tipo embutido.
689
+
Em 2013, fiz((("Python Data Model", "making len work with custom objects")))((("__len__")))
690
+
essa pergunta a Raymond Hettinger, um dos desenvolvedores principais do Python,
691
+
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."
692
+
Na <<how_special_used>>, descrevi como `len(x)` roda muito rápido quando `x` é uma instância de um tipo embutido.
691
693
Nenhum método é chamado para os objetos embutidos do CPython: o tamanho é simplesmente lido de um campo em uma struct C.
692
-
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.
694
+
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
695
+
`str`, `list`, `memoryview`, e assim por diante.
693
696
694
697
Em outras palavras, `len` não é chamado como um método porque recebe um tratamento especial como parte do Modelo de Dados de Python, da mesma forma que `abs`.
695
698
Mas graças ao método especial pass:[<code>__len__</code>], também é possível fazer `len` funcionar com nossos objetos personalizados.
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.
150
150
151
-
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>>.
151
+
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>>.
152
152
153
153
[[ex_unary_plus_counter]]
154
154
.O + unário produz um novo `Counter`sem as contagens negativas ou zero
A((("operator overloading", "overloading + for vector addition", id="OOplus16")))((("mathematical vector operations")))((("+ operator", id="Plusover16")))((("vectors", "overloading + for vector addition", id="Voverload16"))) classe `Vector` é um tipo sequência,
180
-
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 de Python, diz que sequências devem suportar o operador `+` para concatenação e o `+*+` para repetição.
181
-
Entretanto, aqui vamos implementar `+` e `+*+` como operações matemáticas de vetores, algo um pouco mais complicado mas mais significativo para um tipo `Vector`.
180
+
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"]
181
+
do capítulo "Modelo de Dados", na documentação oficial do Python, diz que sequências devem suportar o operador
182
+
`+++` para concatenação e o `+*+` para repetição.
183
+
Entretanto, aqui vamos implementar `+++` e `+*+` como operações matemáticas de vetores, algo um pouco mais complicado porém mais útil para um tipo `Vector`.
182
184
183
185
[TIP]
184
186
====
@@ -255,7 +257,7 @@ Vector([4.0, 6.0, 5.0])
255
257
----
256
258
====
257
259
258
-
Os dois usos de `+` no <<ex_vector_add_demo_mixed_ok>> funcionam porque `+__add__+` usa
260
+
Os dois usos de `+++` no <<ex_vector_add_demo_mixed_ok>> funcionam porque `+__add__+` usa
259
261
`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á.
260
262
261
263
Entretanto, se trocarmos a ordem dos operandos (no <<ex_vector_add_demo_mixed_fail>>), a soma de tipos diferentes falha.
@@ -647,7 +649,7 @@ class Vector:
647
649
all(a == b for a, b in zip(self, other)))
648
650
----
649
651
650
-
Eaae método produz os resultados do <<eq_initial_demo>>.
652
+
Esse método produz os resultados do <<eq_initial_demo>>.
651
653
652
654
[[eq_initial_demo]]
653
655
.Comparando um `Vector` a um `Vector`, a um `Vector2d`, e a uma `tuple`
<5> Durante todo esse exemplo, `globe` sempre se refere ao mesmo objeto que `globe_orig`.
860
862
<6> Tentar adicionar um não-iterável a uma `AddableBingoCage` falha com uma mensagem de erro apropriada.
861
863
862
-
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.
864
+
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.
Copy file name to clipboardExpand all lines: capitulos/cap17.adoc
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -956,7 +956,7 @@ Por isso a próxima seção trata de várias funções geradoras prontas para us
956
956
// 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.
957
957
// ====
958
958
959
-
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`.
959
+
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`.
960
960
961
961
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.
Copy file name to clipboardExpand all lines: capitulos/cap19.adoc
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -218,8 +218,9 @@ Mas chega de conceitos por agora. Vamos ver algum código.((("", startref="CMcon
218
218
[[concurrent_hello_world]]
219
219
=== Um "Olá mundo" concorrente
220
220
221
-
Durante((("concurrency models", "Hello World example", id="CMhello19"))) uma discussão sobre threads e sobre como evitar a GIL, o contribuidor de Python Michele Simionato https://fpy.li/19-10[postou um exemplo] que é praticamente um "Olá Mundo" concorrente:
222
-
o programa mais simples possível mostrando como Python pode "mascar chiclete e subir a escada ao mesmo tempo".
221
+
Durante((("concurrency models", "Hello World example", id="CMhello19"))) uma discussão sobre threads e sobre como evitar a GIL,
222
+
o contribuidor do Python Michele Simionato https://fpy.li/19-10[postou um exemplo] que é praticamente um "Olá Mundo" concorrente:
223
+
o programa mais simples possível mostrando como o Python pode "assobiar e chupar cana ao mesmo tempo".
223
224
224
225
O programa de Simionato usa `multiprocessing`,
225
226
mas eu o adaptei para apresentar também `threading` e `asyncio`.
<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`].
928
928
<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.]
929
929
<5> Mostra o endereço e a porta do primeiro _socket_ do servidor.
930
-
<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.
930
+
<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.
931
931
Sem essa linha, o `supervisor` retornaria imediatamente, encerrando o loop iniciado com `asyncio.run(supervisor(…))`, e fechando o programa. A
932
932
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."
933
933
<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.]
Copy file name to clipboardExpand all lines: capitulos/cap22.adoc
+8-1Lines changed: 8 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1047,7 +1047,14 @@ Revise a <<slots_section>> para recordar esse tópico.
1047
1047
1048
1048
Essas cinco funções embutidas executam leitura, escrita e introspecção de atributos de objetos:
1049
1049
1050
-
`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
diz que o objetivo de `dir` é o uso interativo, então ele não fornece uma lista completa de atributos,
1054
+
mas um conjunto de nomes "interessantes". `dir` pode inspecionar objetos implementados com ou sem um `+__dict__+`.
1055
+
O próprio atributo `+__dict__+` não é exibido por `dir`, mas as chaves de `+__dict__+` são listadas.
1056
+
Vários atributos especiais de classes, tais como
1057
+
1051
1058
`+__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.
1052
1059
1053
1060
`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.
0 commit comments