66[quote, Martijn Faassen, criador de frameworks Python e JavaScript]
77____
88Para uma biblioteca ou framework, ser pythônica significa tornar tão fácil e tão
9- natural quanto possível que uma programadora Python descubra como realizar uma
9+ natural quanto possível que um programador Python descubra como realizar uma
1010tarefa.footnote:[Do post no blog de Faassen intitulado https://fpy.li/11-1[_What
1111is Pythonic?_ (O que é Pythônico?)]]
1212____
@@ -19,7 +19,7 @@ comportarão da forma esperada.
1919
2020Nos capítulos anteriores, estudamos o comportamento de vários objetos embutidos.
2121Vamos agora criar classes definidas pelo usuário que se portam como objetos
22- Python reais . As classes na sua aplicação provavelmente não precisam nem devem
22+ Python nativos . As classes na sua aplicação provavelmente não precisam
2323implementar tantos métodos especiais quanto os exemplos nesse capítulo. Mas se
2424você estiver escrevendo uma biblioteca ou um framework, os programadores que
2525usarão suas classes talvez esperem que elas se comportem como as classes
@@ -38,7 +38,7 @@ exemplo, `repr()`, `bytes()`, `complex()`, etc.)
3838* Estender a mini-linguagem de formatação usada pelas f-strings, pela função
3939embutida `format()` e pelo método `str.format()`
4040* Fornecer acesso a atributos apenas para leitura
41- * Tornar um objetos _hashable_, para uso em _sets_ e como chaves de `dict`
41+ * Tornar um objetos _hashable_, para uso em conjuntos e como chaves de `dict`
4242* Economizar memória com `+__slots__+`
4343
4444Vamos fazer tudo isso enquanto desenvolvemos `Vector2d`, um tipo simples de
@@ -54,17 +54,17 @@ A evolução do exemplo incluirá dois tópicos conceituais importantes:
5454
5555Acrescentei((("Pythonic objects", "significant changes to"))) uma nova epígrafe
5656e também algumas palavras ao segundo parágrafo do capítulo, para falar do
57- conceito de "pythônico"—que na primeira edição era discutido apenas no final do
57+ conceito de "pythônico"—que na primeira edição era mencionado só no final do
5858livro.
5959
60- A <<format_display_sec>> foi atualizada para mencionar as f-strings,
60+ Atualizei a <<format_display_sec>> para mencionar as f-strings,
6161introduzidas no Python 3.6. É uma mudança pequena, pois as f-strings suportam a
6262mesma mini-linguagem de formatação que a função embutida `format()` e o método
6363`str.format()`, então quaisquer métodos `+__format__+` implementados antes vão
6464funcionar também com as f-strings.
6565
6666O resto do capítulo quase não mudou—os métodos especiais são praticamente os mesmos
67- desde o Python 3.0, e as ideias centrais apareceram no Python 2.2.
67+ desde o Python 3.0, e a maioria existe desde o Python 2.2.
6868
6969Vamos começar pelos métodos de representação de objetos.
7070
@@ -80,22 +80,22 @@ uma string representando o objeto como o desenvolvedor quer vê-lo. É o que
8080aparece quando o console de Python ou um depurador mostram um objeto.
8181
8282`str()`:: Devolve((("str() function")))((("functions", "str() function"))) uma
83- string representando o objeto como o usuário quer vê-lo. É o que aparece quando
84- se passa um objeto como argumento para `print()`.
83+ string representando o objeto de uma forma amigável para o usuário final.
84+ É o que aparece quando se passa um objeto como argumento para `print()`.
8585
8686Os((("__repr__")))((("__str__")))
8787métodos especiais `+__repr__+` e `+__str__+` suportam `repr()` e `str()`, como
8888vimos no <<ch_data_model>>.
8989
9090Existem((("__bytes__")))((("__format__")))
91- dois métodos especiais adicionais para suportar representações alternativas de
91+ mais dois métodos especiais para gerar representações alternativas de
9292objetos, `+__bytes__+` e `+__format__+`. O método `+__bytes__+` é análogo a
9393`+__str__+`: ele é chamado por `bytes()` para obter um objeto representado como
9494uma sequência de bytes. Já `+__format__+` é usado por f-strings, pela função
9595embutida `format()` e pelo método `str.format()`. Todos eles chamam
96- `obj.__format__(format_spec )` para obter versões de exibição de objetos usando
97- códigos de formatação especiais. Vamos tratar de `+__bytes__+` na próxima seção
98- e de `+__format__+` logo depois.
96+ `obj.__format__(fmt_spec )`
97+ para gerar uma string exibindo o objeto conforme códigos de formatação especiais.
98+ Vamos tratar de `+__bytes__+` na próxima seção e de `+__format__+` logo depois.
9999
100100
101101[WARNING]
@@ -124,17 +124,15 @@ instância de `Vector2d`.
124124include::../code/11-pythonic-obj/vector2d_v0.py[tags=VECTOR2D_V0_DEMO]
125125----
126126====
127- [role="pagebreak-before less_space"]
128-
129127<1> Os componentes de um `Vector2d` podem ser acessados diretamente como
130128atributos (não é preciso invocar métodos _getter_).
131129<2> Um `Vector2d` pode ser desempacotado para uma tupla de variáveis.
132- <3> O `repr` de um `Vector2d` emula o código-fonte usado para construir a instância.
130+ <3> O `repr` de um `Vector2d` imita o código-fonte usado para construir a instância.
133131<4> Usar `eval` aqui mostra que o `repr` de um `Vector2d` é uma representação
134- fiel da chamada a seu construtor.footnote:[Usei `eval` para clonar o objeto aqui
135- apenas para mostrar uma característica de `repr`; para clonar uma instância, a
132+ fiel da chamada a seu construtor.footnote:[Usei `eval` para clonar o objeto
133+ apenas para demonstrar a sintaxe da string gerada por `repr`; para clonar uma instância, a
136134função `copy.copy` é mais segura e rápida.]
137- <5> `Vector2d` suporta a comparação com `==`; isso é útil para testes.
135+ <5> `Vector2d` suporta a comparação com `==` (muito útil para testes) .
138136<6> `print` chama `str`, que no caso de `Vector2d` exibe um par ordenado.
139137<7> `bytes` usa o método `+__bytes__+` para produzir uma representação binária.
140138<8> `abs` usa o método `+__abs__+` para devolver a magnitude do `Vector2d`.
@@ -161,11 +159,11 @@ include::../code/11-pythonic-obj/vector2d_v0.py[tags=VECTOR2D_V0]
161159`Vector2d` de/para `bytes`.
162160
163161<2> Converter `x` e `y` para `float` em `+__init__+` captura erros mais rápido,
164- algo útil quando `Vector2d` é chamado com argumentos inadequados .
162+ algo útil quando `Vector2d` é chamado com argumentos não numéricos .
165163
166164<3> `+__iter__+` torna um `Vector2d` iterável; é isso que faz o desempacotamento
167- funcionar (por exemplo, `x, y = my_vector`). Vamos implementá-lo aqui usando uma
168- expressão geradora para produzir os componentes, um após outro.footnote:[Essa
165+ funcionar (por exemplo, `x, y = my_vector`). Usamos uma
166+ expressão geradora para produzir os dois componentes, um após outro.footnote:[Essa
169167linha também poderia ser escrita assim: `yield self.x; yield.self.y`. Terei mais
170168a dizer sobre o método especial `+__iter__+`, sobre expressões geradoras e sobre
171169a palavra reservada `yield` no <<ch_generators>>.]
@@ -174,20 +172,20 @@ a palavra reservada `yield` no <<ch_generators>>.]
174172obter seus `repr`; como `Vector2d` é iterável, `*self` alimenta `format` com os
175173componentes `x` e `y`.
176174
177- <5> Dado um iterável `Vector2d`, é fácil criar uma `tuple` para exibição como um
175+ <5> Como `Vector2d` é iterável , é fácil criar uma `tuple` para exibição como um
178176par ordenado.
179177
180178<6> Para gerar `bytes`, convertemos o typecode para `bytes` e concatenamos...
181179
182- <7> ...`bytes` convertidos a partir de um `array` criada iterando sobre a
180+ <7> ...`bytes` convertidos a partir de um `array` criado iterando sobre a
183181instância.
184182
185- <8> Para comparar rapidamente todos os componentes, cria tuplas a partir dos
183+ <8> Para comparar facilmente todos os componentes, criamos tuplas a partir dos
186184operandos. Isso funciona para operandos que sejam instâncias de `Vector2d`, mas
187185tem problemas. Veja o alerta abaixo.
188186
189- <9> A magnitude é o comprimento da hipotenusa do triângulo retângulo de catetos
190- formados pelos componentes `x` e `y`.
187+ <9> A magnitude é o comprimento da hipotenusa do triângulo retângulo
188+ com os catetos formados pelos componentes `x` e `y`.
191189
192190<10> `+__bool__+` usa `abs(self)` para computar a magnitude, então a converte
193191para `bool`; assim, `0.0` se torna `False`, qualquer valor diferente de zero é
@@ -253,20 +251,20 @@ Vamos então falar um pouco disso.
253251O((("Pythonic objects", "classmethod versus staticmethod")))((("classmethod
254252decorator")))((("staticmethod decorator")))((("decorators and closures",
255253"classmethod versus staticmethod"))) decorador `classmethod` não é mencionado no
256- tutorial de Python, nem tampouco o `staticmethod`. Qualquer um que tenha
257- aprendido OO com Java pode se perguntar porque Python tem esses dois
258- decoradores, e não apenas um deles .
254+ tutorial de Python, nem tampouco o `staticmethod`.
255+ Quem OO com Java pode se perguntar porque Python tem esses dois
256+ decoradores, e não apenas `staticmethod` .
259257
260258Vamos começar com `classmethod`. O <<ex_vector2d_v1>> mostra seu uso: definir um
261259método que opera na classe, e não em suas instâncias. O `classmethod` muda a
262260forma como o método é chamado, então recebe a própria classe como primeiro
263261argumento, em vez de uma instância. Seu uso mais comum é em construtores
264262alternativos, como `frombytes` no <<ex_vector2d_v1>>. Observe como a última
265- linha de `frombytes` de fato usa o argumento `cls`, invocando-o para criar uma
263+ linha de `frombytes` o argumento `cls`, invocando-o para criar uma
266264nova instância: `cls(*memv)`.
267265
268266O decorador `staticmethod`, por outro lado, muda um método para que ele não
269- receba qualquer primeiro argumento especial . Essencialmente, um método estático
267+ receba um argumento automaticamente . Essencialmente, um método estático
270268é apenas uma função simples que por acaso mora no corpo de uma classe, em vez de
271269ser definida no nível do módulo. O <<ex_class_staticmethod>> compara a operação
272270de `classmethod` e `staticmethod`.
@@ -303,10 +301,11 @@ a classe `Demo` como primeiro argumento.
303301[NOTE]
304302====
305303O decorador `classmethod` é obviamente útil mas, em minha experiência, bons
306- casos de uso para `staticmethod` são raros. Talvez a função, mesmo sem
307- nunca tocar na classe, seja intimamente relacionada a essa última. Daí você pode
308- querer que ela fique próxima no seu código. E mesmo assim, definir a função logo
309- antes ou logo depois da classe, no mesmo módulo, é perto o suficiente na maioria
304+ casos de uso para `staticmethod` são raros. Talvez a função
305+ seja intimamente relacionada a classe, mesmo sem nunca usá-la em seu corpo.
306+ Daí você pode querer que ela fique próxima no código-fonte.
307+ Mesmo assim, definir a função logo antes ou logo depois da classe,
308+ no mesmo módulo, é perto o suficiente na maioria
310309dos casos.footnote:[Leonardo Rochael, um dos revisores técnicos deste livro,
311310discorda de minha opinião desabonadora sobre o `staticmethod`, e recomenda como
312311contra-argumento o post de blog https://fpy.li/11-2["The Definitive Guide on How
@@ -329,16 +328,16 @@ As((("Pythonic objects", "formatted displays", id="POformat11")))((("functions",
329328method")))((("__format__")))((("f-string syntax",
330329"delegation of formatting by")))((("displays, formatting", id="dispform11")))
331330f-strings, a função embutida `format()` e o método `str.format()` delegam a
332- formatação efetiva para cada tipo, chamando seu método
333- `+.__format__(format_spec)+`. O `format_spec` especifica a formatação desejada,
334- e é:
331+ lógica da formatação para cada tipo, chamando seu método
332+ `+.__format__(fmt_spec)+`.
333+ A string `fmt_spec` especifica a formatação desejada.
334+ Esta especificação é:
335335
336- * O segundo argumento em `format(my_obj, format_spec )`, ou
336+ * O segundo argumento em `format(my_obj, fmt_spec )`, ou
337337
338- * O que quer que apareça após os dois pontos (`:`) em um campo de substituição
339- delimitado por `{}` dentro de uma f-string ou o `fmt ` em `fmt.str .format()`
338+ * O que aparece após os dois pontos (`:`) em um campo de substituição
339+ delimitado por `{}` dentro de uma f-string ou no gabarito `g ` em `g .format()`
340340
341- [role="pagebreak-before less_space"]
342341Por exemplo:
343342
344343[source, python]
@@ -354,21 +353,21 @@ Por exemplo:
354353'1 USD = 4.82 BRL'
355354----
356355
357- <1> A formatação especificada é `'0.4f'`.
356+ <1> A especificação de formato é `'0.4f'`.
358357
359- <2> A formatação especificada é `'0.2f'`. O `rate` no campo de substituição não
358+ <2> A especificação de formato é `'0.2f'`. O `rate` no campo de substituição não
360359é parte da especificação de formato. Ele determina qual argumento nomeado de
361- `.format()` entra no campo de substituição.
360+ `.format()` entra naquele campo de substituição.
362361
363362<3> Novamente, a especificação é `'0.2f'`. A expressão `1 / brl` não é parte
364363dela.
365364
366- O segundo e o terceiro textos explicativos apontam um fato importante: uma
367- string de formatação tal como`'{0.mass:5.3e}'` na verdade usa duas notações
365+ O segundo e o terceiro comentário apontam um fato importante: uma
366+ string de formatação tal como `'{0.mass:5.3e}'` usa duas notações
368367separadas. O `'0.mass'` à esquerda dos dois pontos é a parte `field_name` da
369368sintaxe de campo de substituição, e pode ser uma expressão arbitrária em uma
370- f-string. O `'5.3e'` após os dois pontos é a especificação do formato. A notação
371- usada na especificação do formato é chamada
369+ f-string. O `'5.3e'` após os dois pontos é a especificação do formato.
370+ A notação usada na especificação de formato é chamada
372371https://fpy.li/63[Mini-Linguagem de
373372Especificação de Formato].
374373
@@ -379,13 +378,14 @@ Se f-strings, `format()` e `str.format()` são novidades para você, minha
379378experiência como professor me informa que é melhor estudar primeiro a função
380379embutida `format()`, que usa apenas a
381380https://fpy.li/63[Mini-Linguagem de
382- Especificação de Formato]. Após pegar o jeito desta última, leia
383- https://fpy.li/64["Literais
384- de string formatados"] e
385- https://fpy.li/65["Sintaxe
386- das string de formato"], para aprender sobre a notação de campo de substituição
381+ Especificação de Formato].
382+ Após pegar o jeito dela, leia
383+ https://fpy.li/64["Literais de string formatados"] e
384+ https://fpy.li/65["Sintaxe das string de formato"],
385+ para aprender sobre a notação de campo de substituição
387386(`{:}`), usada em f-strings e no método `str.format()` (incluindo os marcadores
388- de conversão `!s`, `!r`, e `!a`). F-strings não tornam `str.format()` obsoleto:
387+ de conversão `!s`, `!r`, e `!a`). F-strings não tornam o método `str.format()`
388+ obsoleto:
389389na maioria dos casos f-strings resolvem o problema, mas algumas vezes é melhor
390390especificar a string de formatação em outro arquivo (diferente de onde ela será
391391utilizada).
@@ -407,9 +407,10 @@ fixo, e `%`, para exibir porcentagens:
407407----
408408
409409A Mini-Linguagem de Especificação de Formato é extensível, porque cada classe
410- interpreta o argumento `format_spec` como quiser. Por exemplo, as classes no
411- módulo `datetime` usam os mesmos códigos de formatação nas funções `strftime()`
412- e em seus métodos `+__format__+`. Veja abaixo alguns exemplos de uso da função
410+ interpreta o argumento `fmt_spec` como quiser. Por exemplo, as classes no
411+ módulo `datetime` usam em seus métodos `+__format__+` os mesmos códigos
412+ de formatação das funções `strftime()`, que são mais antigas.
413+ Veja abaixo alguns exemplos de uso da função
413414`format()` e do método `str.format()`:
414415
415416[source, python]
@@ -422,8 +423,9 @@ e em seus métodos `+__format__+`. Veja abaixo alguns exemplos de uso da funçã
422423"It's now 06:49 PM"
423424----
424425
425- Se a classe não possuir um `+__format__+`, o método herdado de `object` devolve
426- `str(my_object)`. Como `Vector2d` tem um `+__str__+`, isso funciona:
426+ Se a classe não implementar um `+__format__+`,
427+ o método herdado de `object` devolve `str(my_object)`.
428+ Como `Vector2d` tem um `+__str__+`, isso funciona:
427429
428430[source, python]
429431----
@@ -432,8 +434,8 @@ Se a classe não possuir um `+__format__+`, o método herdado de `object` devolv
432434'(3.0, 4.0)'
433435----
434436
435- Entretanto, se você passar um especificador de formato, `+object.__format__+`
436- gera um `TypeError`:
437+ Entretanto, se você passar um especificador de formato,
438+ `+object.__format__+` gera um `TypeError`:
437439
438440[source, python]
439441----
@@ -443,8 +445,8 @@ Traceback (most recent call last):
443445TypeError: non-empty format string passed to object.__format__
444446----
445447
446- Vamos corrigir isso implementando nossa própria mini-linguagem de formatação. O
447- primeiro passo será presumir que o especificador de formato fornecido pelo
448+ Vamos corrigir isso implementando nossa própria mini-linguagem de formatação.
449+ O primeiro passo será presumir que o especificador de formato fornecido pelo
448450usuário tem por objetivo formatar cada componente `float` do vetor. Esse é o
449451resultado esperado:
450452
@@ -1295,9 +1297,9 @@ pelo método de mesmo nome na classe `array.array`.
12951297Vimos que a
12961298https://fpy.li/63[Mini-Linguagem de
12971299Especificação de Formato] é extensível, ao implementarmos um método
1298- `+__format__+` que analisa uma `format_spec ` fornecida à função embutida
1299- `format(obj, format_spec )` ou dentro de campos de substituição
1300- `'{:«format_spec »}'` em f-strings ou ainda strings usadas com o método
1300+ `+__format__+` que analisa uma `fmt_spec ` fornecida à função embutida
1301+ `format(obj, fmt_spec )` ou dentro de campos de substituição
1302+ `'{:«fmt_spec »}'` em f-strings ou ainda strings usadas com o método
13011303`str.format()`.
13021304
13031305Para preparar a transformação de instâncias de `Vector2d` em _hashable_, fizemos
0 commit comments