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
Copy file name to clipboardExpand all lines: online/cap16.adoc
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -75,11 +75,11 @@ Vamos começar pelo tópico mais fácil: operadores unários.
75
75
76
76
=== Operadores unários
77
77
78
-
A seção https://docs.python.org/pt-br/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations["6.5. Unary arithmetic and bitwise operations" (_Aritmética unária e operações binárias_)] (EN), de _A Referência da Linguagem Python_, elenca((("operator overloading", "unary operators", id="OOunary16")))((("unary operators", id="unary16"))) três operações unárias, listadas abaixo juntamente com seus métodos especiais associados:
78
+
A seção https://fpy.li/7n["6.5. Unary arithmetic and bitwise operations" (_Aritmética unária e operações binárias_)] (EN), de _A Referência da Linguagem Python_, elenca((("operator overloading", "unary operators", id="OOunary16")))((("unary operators", id="unary16"))) três operações unárias, listadas abaixo juntamente com seus métodos especiais associados:
79
79
80
80
`-`, implementado por `+__neg__+`:: Negativo((("__neg__"))) aritmético unário. Se `x` é `-2` então `-x == 2`.
81
81
`{plus}`, implementado por `+__pos__+`:: Positivo((("__pos__"))) aritmético unário. De forma geral, `x == +x`, mas há alguns poucos casos onde isso não é verdadeiro. Veja a <<when_plus_x_sec>>, se estiver curioso.
82
-
`~`, implementado por `+__invert__+`:: Negação((("__invert__"))) binária, ou inversão binária de um inteiro, definida como `~x == -(x+1)`. Se `x` é `2` então `~x == -3`.footnote:[Veja https://pt.wikipedia.org/wiki/L%C3%B3gica_bin%C3%A1ria#NOT[Lógica Binária - NOT] para uma explicação da negação binária.]
82
+
`~`, implementado por `+__invert__+`:: Negação((("__invert__"))) binária, ou inversão binária de um inteiro, definida como `~x == -(x+1)`. Se `x` é `2` então `~x == -3`.footnote:[Veja https://fpy.li/7p[Lógica Binária - NOT] para uma explicação da negação binária.]
83
83
84
84
O pass:[<a href="https://docs.python.org/pt-br/3/reference/datamodel.html#object.__neg__">capítulo "Modelo de Dados"</a>] de _A Referência da Linguagem Python_ também inclui a função embutida `abs()` como um operador unário. O método especial associado é `+__abs__+`, como já vimos.
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.
142
142
143
-
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>>.
143
+
Podemos encontrar o segundo caso onde `x != +x` na https://fpy.li/34[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>>.
144
144
145
145
[[ex_unary_plus_counter]]
146
146
.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,
172
-
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"]
172
+
e a seção https://fpy.li/6n["3.3.7. Emulando de tipos contêineres"]
173
173
do capítulo "Modelo de Dados", na documentação oficial do Python, diz que sequências devem suportar o operador
174
174
`\+` para concatenação e o `\*` para repetição.
175
175
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`.
@@ -939,7 +939,7 @@ A sobrecarga de operadores é uma área da programação em Python onde testes c
939
939
A melhor prática relacionada a tais testes é a _goose typing_, tratada na <<goose_typing_sec>>.
940
940
Se você pulou essa parte, se assegure de voltar lá e ler aquela seção.
941
941
942
-
A principal referência para os métodos especiais de operadores é o https://docs.python.org/pt-br/3/reference/datamodel.html[capítulo "Modelos de Dados"] na documentação de Python. Outra leitura relevante é https://docs.python.org/pt-br/3/library/numbers.html#implementing-the-arithmetic-operations["Implementando as operações aritméticas"] no módulo `numbers` da _Biblioteca Padrão de Python_.
942
+
A principal referência para os métodos especiais de operadores é o https://fpy.li/2j[capítulo "Modelos de Dados"] na documentação de Python. Outra leitura relevante é https://docs.python.org/pt-br/3/library/numbers.html#implementing-the-arithmetic-operations["Implementando as operações aritméticas"] no módulo `numbers` da _Biblioteca Padrão de Python_.
943
943
944
944
Um exemplo brilhante de sobrecarga de operadores apareceu no pacote https://fpy.li/16-13[`pathlib`], adicionado no Python 3.4.
945
945
Sua classe `Path` sobrecarrega o operador `/` para construir caminhos do sistema de arquivos a partir de strings, como mostra o exemplo abaixo, da documentação:
@@ -957,7 +957,7 @@ Na Scapy, o operador `/` operator cria pacotes empilhando campos de diferentes c
957
957
958
958
Se você está prestes a implementar operadores de comparação, estude `functools.total_ordering`.
959
959
Esse é um decorador de classes que gera automaticamente os métodos para todos os operadores de comparação cheia em qualquer classe que defina ao menos alguns deles.
960
-
Veja a https://docs.python.org/pt-br/3/library/functools.html#functools.total_ordering[documentação do módulo functools] (EN).
960
+
Veja a https://fpy.li/7q[documentação do módulo functools] (EN).
961
961
962
962
Se você tiver curiosidade sobre o despacho de métodos de operadores em linguagens com tipagem dinâmica, duas leituras fundamentais são https://fpy.li/16-17["A Simple Technique for Handling Multiple Polymorphism" (_Uma Técnica Simples para Tratar Polimorfismo Múltiplo_)] (EN), de Dan Ingalls (membro da equipe original de Smalltalk), e https://fpy.li/16-18["Arithmetic and Double Dispatching in Smalltalk-80" (_Aritmética e Despacho Duplo em Smalltalk-80_)] (EN), de Kurt J. Hebel e Ralph Johnson (Johnson ficou famoso como um dos autores do livro _Padrões de Projetos_ original). Os dois artigos fornecem discussões profundas sobre o poder do polimorfismo em linguagens com tipagem dinâmica, como Smalltalk, Python e Ruby. Python não tem despacho duplo para tratar operadores, como descrito naqueles artigos. O algoritmo de Python, usando operadores diretos e reversos, é mais fácil de suportar por classes definidas pelo usuário que o despacho duplo, mas exige tratamento especial pelo interpretador. Por outro lado, o despacho duplo clássico é uma técnica geral, que pode ser usada no Python ou em qualquer linguagem orientada a objetos, para além do contexto específico de operadores infixos. E, de fato, Ingalls, Hebel e Johnson usam exemplos muito diferentes para descrever essa técnica.
0 commit comments