Skip to content

Commit 23832b9

Browse files
committed
vol2: cap 11 e 12: paginação
1 parent 390b14c commit 23832b9

File tree

8 files changed

+131
-113
lines changed

8 files changed

+131
-113
lines changed

code/11-pythonic-obj/vector2d_v3.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
'(3.000e+00, 4.000e+00)'
4343
4444
45+
46+
4547
Tests of the `.angle()` method::
4648
4749
>>> Vector2d(0, 0).angle()

code/12-seq-hacking/vector_v1.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@
8787
import reprlib
8888
import math
8989

90-
9190
class Vector:
9291
typecode = 'd'
9392

code/12-seq-hacking/vector_v2.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ def __bool__(self):
148148
# tag::VECTOR_V2[]
149149
def __len__(self):
150150
return len(self._components)
151+
151152

152153
def __getitem__(self, key):
153154
if isinstance(key, slice): # <1>

online/cap11.adoc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ trabalhando no `Vector2d` há algum tempo, mostrando apenas trechos isolados. O
761761
_vector2d_v3.py_, incluindo os doctests que usei durante o desenvolvimento.
762762

763763
[[ex_vector2d_v3_full]]
764-
.vector2d_v3.py: o pacote completo
764+
.vector2d_v3.py: o módulo completo
765765
====
766766
[source, python]
767767
----
@@ -835,8 +835,8 @@ O <<name_mangling_ex>> mostra o resultado na classe `Vector2d` do <<ex_vector2d_
835835
====
836836

837837
A desfiguração do nome oferece proteção, não segurança:
838-
ela pode evitar acessos acidentais, mas não ataques intencionais.
839-
A <<safety_fig>> ilustra outro dispositivo de proteção.
838+
pode evitar acessos acidentais, mas não ataques intencionais.
839+
A <<safety_fig>> mostra um dispositivo de proteção.
840840

841841
[[safety_fig]]
842842
.A capa sobre um interruptor é um dispositivo de proteção, não de segurança: previne acidentes, não sabotagem
@@ -850,9 +850,9 @@ atribuir um valor a um componente privado de um `Vector2d`, escrevendo
850850
não poderá reclamar se alguma coisa explodir.
851851

852852
A funcionalidade de desfiguração de nomes não é amada por todos os pythonistas,
853-
nem tampouco a aparência estranha de nomes escritos como `self.__x`. Muitos
853+
nem tampouco a aparência estranha de nomes escritos como `+self.__x+`. Muitos
854854
preferem evitar essa sintaxe e usar apenas um sublinhado no prefixo para
855-
"proteger" atributos por convenção: `self._x`. Críticos da
855+
"proteger" atributos por convenção: `+self._x+`. Críticos da
856856
desfiguração automática com o sublinhado duplo dizem que preocupações com
857857
modificações acidentais a atributos devem ser tratadas através de convenções
858858
de nomenclatura. O criador do _pip_, _virtualenv_ e outros
@@ -1327,7 +1327,7 @@ resumido em uma só frase, seria essa:
13271327

13281328
[quote, Antigo provérbio chinês]
13291329
____
1330-
Para criar objetos pythônicos, observe como se comportam objetos reais de Python.
1330+
Para criar objetos pythônicos, observe como se comportam os objetos do Python.
13311331
____
13321332

13331333
[[pythonic_reading_sec]]

online/cap12.adoc

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,11 @@ Quando um `Vector` tem mais de seis componentes, a string produzida por `repr()`
117117
`\...`, como visto na última linha do <<ex_vector_demo>>. Isso é fundamental para qualquer tipo de coleção que possa conter um número grande de itens, pois `repr` é usado na depuração—e você não quer que um único objeto grande ocupe milhares de linhas em seu console ou arquivo de log. Use o módulo `reprlib` para produzir representações de tamanho limitado, como no <<ex_vector_v1>>. O módulo `reprlib` se chamava `repr` no Python 2.7.
118118
====
119119

120-
O <<ex_vector_v1>> lista a implementação de nossa primeira versão de `Vector`
121-
(este exemplo usa como base o código mostrado no <<ex_vector2d_v0>> e
122-
<<ex_vector2d_v1>> do <<ch_pythonic_obj>>).
120+
O <<ex_vector_v1>> é a primeira versão de `Vector`
121+
baseada no <<ex_vector2d_v0>> e <<ex_vector2d_v1>> do <<ch_pythonic_obj>>.
123122

124123
[[ex_vector_v1]]
125-
.vector_v1.py: derived from vector2d_v1.py
124+
.vector_v1.py: baseado em vector2d_v1.py
126125
====
127126
[source, python]
128127
----
@@ -161,8 +160,8 @@ dentro de um `Vector` é um detalhe de implementação. Como essas chamadas ao
161160
construtor criam objetos `Vector` idênticos, preferi a sintaxe mais simples,
162161
usando um argumento `list`.
163162

164-
Ao escrever o `+__repr__+`, eu poderia construir uma string para exibição
165-
simplificada de `components` com este código:
163+
Ao escrever o `+__repr__+`, eu poderia construir uma string para exibir
164+
`components` com este código:
166165
`reprlib.repr(list(self._components))`.
167166
Mas isto teria um custo adicional, pois eu estaria copiando cada item de `self._components` para uma
168167
`list` só para usar a `list` no `repr`. Em vez disso, decidi aplicar
@@ -240,24 +239,25 @@ se exatamente como a classe será utilizada.
240239
Por exemplo, apenas `+__getitem__+` é necessário para suportar iteração;
241240
não é preciso implemtar `+__len__+`.
242241

243-
[role="man-height4"]
242+
244243
[TIP]
245244
====
245+
246246
Com((("protocol classes")))((("protocols", "static protocols"))) a
247247
https://fpy.li/pep544[_PEP 544—Protocols: Structural subtyping (static duck typing)_]
248248
(Protocolos: sub-tipagem estrutural (tipagem pato estática))],
249249
o Python 3.8 suporta _classes protocolo_: subclasses de `typing.Protocol`,
250-
que estudamos na <<protocols_in_fn_sec>>.
251-
Esse novo uso da palavra protocolo no Python tem um significado parecido, mas não idêntico.
250+
que estudamos na https://fpy.li/8m[«Seção 8.5.10»] (vol.1).
251+
Este novo uso da palavra "protocolo" no Python tem um significado parecido, mas não idêntico.
252252
Quando preciso diferenciá-los, escrevo((("static protocols", "versus dynamic protocols",
253253
secondary-sortas="dynamic protocols")))
254-
255-
_protocolo estático_ para me referir aos protocolos formalizados em classes
256-
protocolo (subclasses de `typing.Protocol`), e((("dynamic protocols")))
257-
_protocolos dinâmicos_ para o sentido tradicional. Uma diferença fundamental é
254+
"protocolo estático" para me referir a um protocolos formalizado por uma classe
255+
subclasse de `typing.Protocol`, e((("dynamic protocols")))
256+
"protocolo dinâmico" para me referir ao sentido tradicional.
257+
Uma diferença fundamental é que
258258
uma implementação de um protocolo estático precisa oferecer todos os métodos
259259
definidos na classe protocolo. A <<two_kinds_protocols_sec>>
260-
(<<ch_ifaces_prot_abc>>) traz mais detalhes.
260+
apresentará muito mais detalhes.
261261
262262
====
263263

@@ -281,8 +281,7 @@ são um bom começo:
281281
[source, python]
282282
----
283283
class Vector:
284-
# many lines omitted
285-
# ...
284+
# muitas linhas omitidas...
286285
287286
def __len__(self):
288287
return len(self._components)
@@ -291,7 +290,7 @@ class Vector:
291290
return self._components[index]
292291
----
293292

294-
Após tais acréscimos, agora as seguintes operações funcionam:
293+
Com tais acréscimos, as seguintes operações funcionam:
295294

296295
[source, python]
297296
----
@@ -381,7 +380,7 @@ Vamos agora olhar mais de perto a própria classe `slice`, no <<ex_slice1>>.
381380
No <<ex_slice1>>, a chamada `dir(slice)` revela um atributo `indices`, um método
382381
pouco conhecido mas muito interessante. Eis o que diz `help(slice.indices)`:
383382

384-
`S.indices(len) -> (start, stop, stride)`::
383+
`S.indices(len) {rt-arrow} (start, stop, stride)`::
385384
Supondo uma sequência de tamanho `len`, calcula os índices `start` (_início_) e `stop` (_fim_), e a extensão do `stride` (_passo_) da fatia estendida descrita por `S`. Índices fora dos limites são recortados, exatamente como acontece em uma fatia normal.
386385

387386
Em outras palavras, o método `indices` expõe a lógica complexa implementada nas
@@ -867,9 +866,8 @@ Mas não para grandes vetores multidimensionais. Uma forma melhor de comparar um
867866
return True # <4>
868867
----
869868
====
870-
<1> Se as `len` dos objetos são diferentes, eles não são iguais.
871-
Este teste é importante porque o `zip` encerra a iteração
872-
assim que o primeiro argumento é consumido.
869+
<1> Objetos de tamanho diferentes não são iguais.
870+
Teste necessário porque `zip` retorna quando termina o iterável menor.
873871
<2> `zip` produz um gerador de tuplas criadas a partir dos itens em cada argumento iterável.
874872
<3> Sai assim que dois componentes sejam diferentes, devolvendo `False`.
875873
<4> Caso contrário, os objetos são iguais.
@@ -1281,9 +1279,9 @@ o uso do `*` como opção de formatação.
12811279
12821280
Na((("Soapbox sidebars", "Pythonic sums",
12831281
id="SSpysum12")))((("Pythonic sums", id="pysum12")))
1284-
https://fpy.li/12-11[Python-list], há uma thread de abril de 2003 chamada
1285-
https://fpy.li/12-12[Pythonic Way to Sum n-th List Element?] (A forma
1286-
pythônica de somar o n-ésimo elemento em listas).
1282+
https://fpy.li/12-11[_python-list_], há uma thread de abril de 2003 intitulada
1283+
https://fpy.li/12-12[_Pythonic Way to Sum n-th List Element?_]
1284+
(A forma pythônica de somar o n-ésimo elemento em listas).
12871285
12881286
Não há uma resposta única para a "O que é pythônico?", da mesma
12891287
forma que não há uma resposta única para "O que é belo?"

vol2/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ e faço as demais tarefas nestas cópias especiais para impressão.
1515
|||||||||`/vol2`| refazer referências entre volumes|
1616
|||||||||`/vol2`| encurtar links entre volumes |
1717
|||||||||`/vol2`| exibir capítulo alvo em xrefs para exemplos de outros capítulos |
18-
||| | | | | | |`/vol2`| rever paginação |
18+
|||| | | | | |`/vol2`| rever paginação |
1919

vol2/cap11.adoc

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,27 @@ instância de `Vector2d`.
124124
include::../code/11-pythonic-obj/vector2d_v0.py[tags=VECTOR2D_V0_DEMO]
125125
----
126126
====
127+
127128
<1> Os componentes de um `Vector2d` podem ser acessados diretamente como
128129
atributos (não é preciso invocar métodos _getter_).
130+
129131
<2> Um `Vector2d` pode ser desempacotado para uma tupla de variáveis.
132+
130133
<3> O `repr` de um `Vector2d` imita o código-fonte usado para construir a instância.
134+
131135
<4> Usar `eval` aqui mostra que o `repr` de um `Vector2d` é uma representação
132136
fiel da chamada a seu construtor.footnote:[Usei `eval` para clonar o objeto
133137
apenas para demonstrar a sintaxe da string gerada por `repr`; para clonar uma instância, a
134138
função `copy.copy` é mais segura e rápida.]
139+
135140
<5> `Vector2d` suporta a comparação com `==` (muito útil para testes).
141+
136142
<6> `print` chama `str`, que no caso de `Vector2d` exibe um par ordenado.
143+
137144
<7> `bytes` usa o método `+__bytes__+` para produzir uma representação binária.
145+
138146
<8> `abs` usa o método `+__abs__+` para devolver a magnitude do `Vector2d`.
147+
139148
<9> `bool` usa o método `+__bool__+` para devolver `False` se o `Vector2d`
140149
tiver magnitude zero, caso contrário esse método devolve `True`.
141150

@@ -146,6 +155,7 @@ métodos para os operadores `{plus}` e `*`, que veremos mais tarde no
146155
escrever testes. Nesse ponto, `Vector2d` usa vários métodos especiais para oferecer
147156
operações que um pythonista espera encontrar em um objeto bem projetado.
148157

158+
<<<
149159
[[ex_vector2d_v0]]
150160
.vector2d_v0.py: todos os métodos até aqui são métodos especiais
151161
====
@@ -581,9 +591,9 @@ Para tornar um `Vector2d` _hashable_, precisamos implementar `+__hash__+`
581591
precisamos tornar imutáveis as instâncias do vetor, como vimos na
582592
https://fpy.li/8t[«Seção 3.4.1»] (vol.1).
583593

584-
Nesse momento, qualquer um pode fazer `v1.x = 7`,
585-
e não há nada no código sugerindo que é proibido modificar um `Vector2d`.
586-
O comportamento que queremos é o seguinte:
594+
Nesse momento, qualquer um pode fazer `v1.x = 7`.
595+
Nada no código proíbe modificar um `Vector2d`.
596+
Mas o comportamento que queremos é o seguinte:
587597

588598
[source, python]
589599
----
@@ -599,7 +609,7 @@ Faremos isso transformando os componentes `x` e `y` em propriedades apenas para
599609
leitura no <<ex_vector2d_v3>>.
600610

601611
[[ex_vector2d_v3]]
602-
.vector2d_v3.py: apenas as mudanças necessárias para tornar `Vector2d` imutável são exibidas aqui; a listagem completa está no <<ex_vector2d_v3_full>>
612+
.vector2d_v3.py: as mudanças necessárias para tornar `Vector2d` imutável aparecem aqui; a listagem completa está no <<ex_vector2d_v3_full>>
603613
====
604614
[source, python]
605615
----
@@ -620,10 +630,9 @@ ele expõe: `x`.
620630

621631
<5> Repete a mesma fórmula para a propriedade `y`.
622632

623-
<6> Todos os métodos que apenas leem os componentes `x` e `y` podem permanecer
624-
como estavam, lendo as propriedades públicas através de `self.x` e `self.y` em
625-
vez de usar os atributos privados. Então essa listagem omite o restante do
626-
código da classe.
633+
<6> Todos os métodos que apenas leem os componentes `x` e `y` podem continuar
634+
lendo as propriedades públicas através de `self.x` e `self.y` em vez de usar os
635+
atributos privados. Por isso omiti o resto da classe.
627636

628637
[NOTE]
629638
====
@@ -717,17 +726,14 @@ o resultado é esse:
717726
TypeError: Vector2d() accepts 0 positional sub-patterns (1 given)
718727
----
719728

720-
Para fazer `Vector2d` funcionar com padrões posicionais, precisamos acrescentar
729+
Para fazer `Vector2d` funcionar com padrões posicionais, precisamos criar
721730
um atributo de classe chamado `+__match_args__+`, listando os atributos de
722-
instância na ordem em que eles serão usados no pattern matching posicional.
723-
731+
instância na ordem em que eles serão usados no pattern matching posicional:
724732

725733
[source, python]
726734
----
727735
class Vector2d:
728736
__match_args__ = ('x', 'y')
729-
730-
# etc...
731737
----
732738

733739
Agora podemos escrever menos código ao criar padrões para casar com
@@ -760,7 +766,7 @@ trabalhando no `Vector2d` há algum tempo, mostrando apenas trechos isolados. O
760766
_vector2d_v3.py_, incluindo os doctests que usei durante o desenvolvimento.
761767

762768
[[ex_vector2d_v3_full]]
763-
.vector2d_v3.py: o pacote completo
769+
.vector2d_v3.py: o módulo completo
764770
====
765771
[source, python]
766772
----
@@ -789,6 +795,7 @@ Como programado no <<ex_vector2d_v3_full>>, `Vector2d` é um exemplo didático
789795
com uma longa lista de métodos especiais relacionados à representação de
790796
objetos, não um modelo para qualquer classe que você vai escrever.
791797

798+
<<<
792799
Na próxima seção, deixamos o `Vector2d` de lado por um tempo para discutir o
793800
design e as limitações do mecanismo de atributos privados no Python—o prefixo
794801
de duplo sublinhado em `self.__x`.((("", startref="POvectorfull11")))((("",
@@ -833,9 +840,10 @@ O <<name_mangling_ex>> mostra o resultado na classe `Vector2d` do <<ex_vector2d_
833840
----
834841
====
835842

843+
<<<
836844
A desfiguração do nome oferece proteção, não segurança:
837-
ela pode evitar acessos acidentais, mas não ataques intencionais.
838-
A <<safety_fig>> ilustra outro dispositivo de proteção.
845+
evita acessos acidentais, mas não intencionais.
846+
A <<safety_fig>> mostra um dispositivo de proteção.
839847

840848
[[safety_fig]]
841849
.A capa sobre um interruptor é um dispositivo de proteção, não de segurança: previne acidentes, não sabotagem
@@ -849,9 +857,9 @@ atribuir um valor a um componente privado de um `Vector2d`, escrevendo
849857
não poderá reclamar se alguma coisa explodir.
850858

851859
A funcionalidade de desfiguração de nomes não é amada por todos os pythonistas,
852-
nem tampouco a aparência estranha de nomes escritos como `self.__x`. Muitos
860+
nem tampouco a aparência estranha de nomes escritos como `+self.__x+`. Muitos
853861
preferem evitar essa sintaxe e usar apenas um sublinhado no prefixo para
854-
"proteger" atributos por convenção: `self._x`. Críticos da
862+
"proteger" atributos por convenção: `+self._x+`. Críticos da
855863
desfiguração automática com o sublinhado duplo dizem que preocupações com
856864
modificações acidentais a atributos devem ser tratadas através de convenções
857865
de nomenclatura. O criador do _pip_, _virtualenv_ e outros
@@ -899,8 +907,8 @@ Java nesse aspecto, nem leia minha discussão sobre a força relativa do
899907
modificador `private` de Java no <<pythonic_soapbox>>.]
900908

901909
Vamos agora voltar à nossa classe `Vector2d`. Na próxima seção trataremos de um
902-
atributo especial (e não um método) que afeta o armazenamento interno de um
903-
objeto, reduzindo o uso de memória, mas sem afetar muito
910+
atributo especial (não um método) que
911+
reduz o uso de memória das instâncias, sem afetar muito
904912
sua interface pública: `+__slots__+`.((("",
905913
startref="Aprivate11")))((("", startref="POprivate11")))
906914

@@ -922,7 +930,7 @@ nomeados em `+__slots__+` serão armazenados em um array de referências oculto,
922930
que usa menos memória que um `dict`. Vamos ver como isso funciona através de
923931
alguns exemplos simples, começando pelo <<slots_ex1>>.
924932

925-
933+
<<<
926934
[[slots_ex1]]
927935
.A classe `Pixel` usa `+__slots__+`
928936
====
@@ -996,14 +1004,14 @@ no final.
9961004
<3> Você pode definir atributos declarados no `+__slots__+` dessa classe e nos
9971005
de suas superclasses, mas nenhum outro.
9981006

999-
Curiosamente, também é possível colocar o nome `'+__dict__+'` em `+__slots__+`.
1007+
Curiosamente, também é possível colocar o nome `+'__dict__'+` em `+__slots__+`. +
10001008
Neste caso, as instâncias vão manter os atributos nomeados em `+__slots__+` num
10011009
array de referências da instância, mas também vão aceitar atributos criados
10021010
dinamicamente, que serão armazenados `+__dict__+`, como de costume.
1003-
Isso é necessário para usar o decorador `@cached_property` (tratado na
1004-
https://fpy.li/7x[«Seção 22.3.5»] (vol.3)).
1011+
Isso é necessário para usar o decorador `@cached_property`, tratado na
1012+
https://fpy.li/7x[«Seção 22.3.5»] (vol.3).
10051013

1006-
Naturalmente, incluir `+__dict__+` em `+__slots__+` pode anular a economia
1014+
Naturalmente, incluir `+'__dict__'+` em `+__slots__+` pode anular a economia
10071015
de memória, dependendo do número de atributos estáticos e
10081016
dinâmicos em cada instância, e de como eles são usados.
10091017
Otimização descuidada é pior que otimização prematura:
@@ -1017,8 +1025,9 @@ instâncias de classes definidas pelo usuário. Entretanto, se a classe define
10171025
fracas, então é preciso incluir `+__weakref__+` entre os atributos nomeados em
10181026
`+__slots__+`.
10191027

1020-
Vejamos agora o efeito da adição de `+__slots__+` a `Vector2d`.
1028+
Vejamos agora o efeito de `+__slots__+` em `Vector2d`.
10211029

1030+
<<<
10221031
==== Uma medida simples da economia gerada por `+__slots__+`
10231032

10241033
<<ex_vector2d_v3_slots>> mostra a implementação de `+__slots__+` em `Vector2d`.
@@ -1326,7 +1335,7 @@ resumido em uma só frase, seria essa:
13261335

13271336
[quote, Antigo provérbio chinês]
13281337
____
1329-
Para criar objetos pythônicos, observe como se comportam objetos reais de Python.
1338+
Para criar objetos pythônicos, observe como se comportam os objetos do Python.
13301339
____
13311340

13321341
[[pythonic_reading_sec]]
@@ -1542,3 +1551,5 @@ você pelo Python. E use esse poder com
15421551
responsabilidade.((("", startref="POsoap11")))
15431552
15441553
****
1554+
1555+
<<<

0 commit comments

Comments
 (0)