Skip to content

Commit 4eea12c

Browse files
committed
vol2: preparando para imprimir
1 parent f221f57 commit 4eea12c

File tree

13 files changed

+267
-162
lines changed

13 files changed

+267
-162
lines changed

code/11-pythonic-obj/vector2d_v3.py

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

links/FPY.LI.htaccess

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ RedirectTemp /11-9 https://docs.python.org/3/tutorial/modules.html#more-on-modul
467467
RedirectTemp /11-10 https://docs.python.org/3/library/gettext.html#gettext.NullTranslations
468468
RedirectTemp /11-11 https://github.com/fluentpython/example-code-2e/blob/master/11-pythonic-obj/mem_test.py
469469
RedirectTemp /11-12 https://docs.python.org/3/reference/datamodel.html#basic-customization
470-
RedirectTemp /11-13 http://esug.org/data/HistoricalDocuments/TheSmalltalkReport/ST07/04wo.pdf
470+
RedirectTemp /11-13 https://rmod-files.lille.inria.fr/FreeBooks/TheSmalltalkReport/PDFS/ST/ST07/04WO.PDF
471471
RedirectTemp /11-14 https://www.artima.com/articles/the-simplest-thing-that-could-possibly-work#part3
472472
RedirectTemp /11-15 https://docs.oracle.com/javase/tutorial/essential/environment/security.html
473473
RedirectTemp /11-16 https://github.com/fluentpython/example-code-2e/blob/master/11-pythonic-obj/private/Expose.java

online/cap09.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ apresento o decorador de _caching_ `functools.cache` do Python
7373
A <<lru_cache_sec>> apresenta também o uso de `lru_cache`
7474
sem argumentos, uma novidade do Python 3.8.
7575

76-
Expandi a <<generic_functions_sec>> para incluir dicas de tipo, a sintaxe
76+
Expandi a <<single_dispatch_sec>> para incluir dicas de tipo, a sintaxe
7777
recomendada para usar `functools.singledispatch` desde o Python 3.7.
7878

7979
A <<parameterized_dec_sec>> agora inclui o <<clockdeco_param_cls_ex>>,
@@ -1088,7 +1088,7 @@ def costly_function(a, b):
10881088

10891089
Vamos agora examinar outro decorador poderoso: `functools.singledispatch`.
10901090

1091-
[[generic_functions_sec]]
1091+
[[single_dispatch_sec]]
10921092
==== Funções genéricas com despacho único
10931093

10941094
Imagine((("single dispatch generic functions",

online/cap10.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ discussion")))((("Soapbox sidebars", "design patterns"))) tem funções de
654654
primeira classe e tipos de primeira classe, e Norvig afima que esses recursos
655655
afetam 10 dos 23 padrões (slide 10 de
656656
https://fpy.li/norvigdp[_Design Patterns in Dynamic Languages_]).
657-
Na <<generic_functions_sec>>, vimos que Python também tem funções
657+
Na <<single_dispatch_sec>>, vimos que Python também tem funções
658658
genéricas de despacho único, uma forma limitada dos multi-métodos do
659659
CLOS, que Gamma et al. sugerem como uma maneira mais simples de implementar o
660660
padrão clássico Visitante (_Visitor_). Norvig, por outro lado, diz (no slide 10)

vol2/Copyright-cor.adoc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[colophon%discrete%notitle%nonfacing,toclevels=0]
22
= Copyright
3-
:isbn-cor: XXXX
4-
:isbn-pb: XXXX
3+
:isbn-cor: 978-65-989778-2-5
4+
:isbn-pb: 978-65-989778-3-2
55

66
Tradução autorizada em português de
77
_Fluent Python, 2nd Edition_ +
@@ -19,8 +19,8 @@ O autor mantém uma versão online em https://PythonFluente.com.
1919
Autor: Luciano Ramalho +
2020
Título: Python Fluente, 2ª edição, volume 2: classes e protocolos +
2121
Primeira edição: 2015 +
22-
Edição atual: setembro/2025 +
23-
{revisao}ª revisão: `pyfl-vol2-rev{revisao}-cor.pdf`
22+
Edição atual: janeiro/2026 +
23+
Revisão: `pyfl2-vol2-cor-2026-01-15.pdf`
2424

2525
Tradução da 2ª edição: Paulo Candido de Oliveira Filho +
2626
Ilustração de capa: Thiago Castor (xilogravura "Calango") +
@@ -37,7 +37,7 @@ R135p Ramalho, Luciano.
3737
Luciano Ramalho - São Paulo, SP - Z.Edições, 2025.
3838
400 f.; il.; cor; 17 cm × 24 cm
3939
40-
ISBN: XXX-XX-XXXXXX-X-X
40+
ISBN: 978-65-989778-2-5
4141
1.Informática. 2.Linguagem de Programação. 3.Python.
4242
4.Metaprogramação.
4343

vol2/Copyright-pb.adoc

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
[colophon%discrete%notitle%nonfacing,toclevels=0]
2+
= Copyright
3+
:isbn-pb: 978-65-989778-3-2
4+
:isbn-cor: 978-65-989778-2-5
5+
6+
Tradução autorizada em português de
7+
_Fluent Python, 2nd Edition_ +
8+
ISBN 978-1-492-05635-5
9+
© 2022 Luciano Ramalho. +
10+
Esta tradução é publicada e vendida com a permissão da O'Reilly Media, Inc.,
11+
detentora dos direitos para publicação e venda desta obra.
12+
13+
© 2025 Luciano Ramalho. +
14+
_Python Fluente, 2ª edição_ está publicado sob a licença
15+
CC BY-NC-ND 4.0 +
16+
_Atribuição-NãoComercial-SemDerivações 4.0 Internacional_ [.small]#&#91;fpy.li/ccby&#93;#. +
17+
O autor mantém uma versão online em https://PythonFluente.com.
18+
19+
Autor: Luciano Ramalho +
20+
Título: Python Fluente, 2ª edição, volume 2: classes e protocolos +
21+
Primeira edição: 2015 +
22+
Edição atual: janeiro/2026 +
23+
Revisão: `pyfl2-vol2-pb-2026-01-15.pdf`
24+
25+
Tradução da 2ª edição: Paulo Candido de Oliveira Filho +
26+
Ilustração de capa: Thiago Castor (xilogravura "Calango") +
27+
Design da capa: Luciano Ramalho, Zander Catta Preta @ Z•Edições +
28+
Design do miolo: Luciano Ramalho, com Asciidoctor +
29+
Ficha catalográfica: Edison Luís dos Santos
30+
31+
Publisher: Heinar Maracy @ Z•Edições
32+
33+
----
34+
R135p Ramalho, Luciano.
35+
36+
Python Fluente, 2a edição, volume 2: classes e protocolos /
37+
Luciano Ramalho - São Paulo, SP - Z.Edições, 2025.
38+
364 p.; il.; 17 cm × 24 cm
39+
40+
ISBN: 978-65-989778-3-2
41+
1.Informática. 2.Linguagem de Programação. 3.Python.
42+
4.Metaprogramação.
43+
44+
I.Título II.Dados e funções III.RAMALHO, Luciano.
45+
46+
CDU: 004.438
47+
CDD: 005.133
48+
----

vol2/cap09.adoc

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
:example-number: 0
44
:figure-number: 0
55

6-
[quote, PEP 318—Decorators for Functions and Methods ("Decoradores para Funções e Métodos"—EN)]
6+
[quote, PEP 318—Decorators for Functions and Methods]
77
____
88
Houve uma certa quantidade de reclamações sobre a escolha do nome "decorador"
99
para esse recurso. A mais frequente foi sobre o nome não ser consistente com seu
1010
uso no livro da GoF.footnote:[GoF se refere ao livro __Design Patterns__
11-
(traduzido no Brasil como _"Padrões de Projeto"_), de 1985. Seus quatro
12-
autores ficaram conhecidos como a "Gang of Four" (_Gangue dos Quatro_).] O nome
11+
(traduzido no Brasil como Padrões de Projeto). Seus
12+
autores ficaram conhecidos como a _Gang of Four_ (Gangue dos Quatro).] O nome
1313
++decorator++ provavelmente se origina de seu uso no âmbito dos
1414
compiladores--uma árvore sintática é percorrida e anotada.
1515
____
@@ -53,6 +53,7 @@ capítulo é explicar exatamente como funcionam os decoradores de função, desd
5353
simples decoradores de registro até os complicados decoradores parametrizados.
5454
Mas antes de chegar a esse objetivo, precisamos tratar de:
5555

56+
<<<
5657
* Como Python analisa a sintaxe de decoradores
5758
* Como Python decide se uma variável é local
5859
* Por que clausuras existem e como elas funcionam
@@ -72,7 +73,7 @@ apresento o decorador de _caching_ `functools.cache` do Python
7273
3.9 antes do `functools.lru_cache`, que é mais antigo.
7374
A <<lru_cache_sec>> apresenta também o uso de `lru_cache`
7475
sem argumentos, uma novidade do Python 3.8.
75-
Expandi a <<generic_functions_sec>> para incluir dicas de tipo, a sintaxe
76+
Expandi a <<single_dispatch_sec>> para incluir dicas de tipo, a sintaxe
7677
recomendada para usar `functools.singledispatch` desde o Python 3.7.
7778
A <<parameterized_dec_sec>> agora inclui o <<clockdeco_param_cls_ex>>,
7879
que usa uma classe e não uma clausura para implementar um decorador.
@@ -90,9 +91,11 @@ devolver a mesma função ou substituí-la por outra função ou objeto invocáv
9091
você substituir "função" por "classe" na sentença anterior, o resultado é uma
9192
descrição resumida do papel de um decorador de classe, assunto que veremos no
9293
https://fpy.li/24[«Capítulo 24»] (vol.3).]
94+
9395
Em outras palavras, supondo a existência de uma função decoradora
9496
chamada `decorate`, este código:
9597

98+
<<<
9699
[source, python]
97100
----
98101
@decorate
@@ -143,7 +146,6 @@ running inner()
143146
<3> Invocar a `target` decorada causa, na verdade, a execução de `inner`.
144147
<4> A inspeção revela que `target` é agora uma referência a `inner`.
145148

146-
147149
Estritamente falando, decoradores são apenas açúcar sintático. Como vimos, é
148150
sempre possível chamar um decorador como um invocável normal, passando outra
149151
função como parâmetro. Algumas vezes isso inclusive é conveniente, especialmente
@@ -203,7 +205,6 @@ Observe que `register` roda (duas vezes) antes de qualquer outra função no
203205
módulo. Quando `register` é chamada, ela recebe o objeto função a ser decorado
204206
como argumento—por exemplo, `<function f1 at 0x100631bf8>`.
205207

206-
<<<
207208
Após o carregamento do módulo, a lista `registry` contém referências para as
208209
duas funções decoradas: `f1` e `f2`. Essas funções, bem como `f3`, são executadas
209210
apenas quando chamadas explicitamente por `main`.
@@ -300,7 +301,6 @@ atribuirmos um valor a um `b` global e então chamarmos `f1`, funciona:
300301

301302
Agora vamos ver um exemplo que pode ser surpreendente.
302303

303-
<<<
304304
Leia com atenção a função `f2`, no <<ex_local_unbound>>. As primeiras duas linhas
305305
são as mesmas da `f1` do <<ex_global_undef>>, e então ela faz uma atribuição a
306306
`b`. Mas para com um erro no segundo `print`, antes da atribuição ser executada.
@@ -369,11 +369,11 @@ Nos exemplos anteriores, vimos dois escopos em ação:
369369
O escopo global do módulo:: Composto((("scope", "module global scope"))) por
370370
nomes atribuídos a valores fora de qualquer bloco de classe ou função.
371371

372-
O escopo local da função f3:: Composto((("scope", "function local scope"))) por
372+
O escopo local da função `f3`:: Composto((("scope", "function local scope"))) por
373373
nomes atribuídos a valores como parâmetros, ou diretamente no corpo da função.
374374

375-
Há um outro escopo de onde variáveis podem vir, chamado _nonlocal_, e ele é
376-
fundamental para clausuras; vamos tratar disso em breve.
375+
Há um outro escopo onde variáveis podem existir, chamado _nonlocal_ (não-local).
376+
Ele ocorre quando há funções aninhadas; vamos tratar disso em breve.
377377

378378
Agora que vimos como o escopo de variáveis funciona no Python, podemos
379379
enfrentar as clausuras na <<closures_sec>>.
@@ -455,17 +455,17 @@ https://fpy.li/5x["dis—Disassembler de bytecode de Python"].
455455
=== Clausuras
456456

457457
Na((("decorators and closures", "closure basics", id="DACclos09")))((("anonymous
458-
functions"))) blogosfera, as clausuras são algumas vezes confundidas com funções
459-
anônimas. Muita gente confunde por causa da história paralela destes conceitos:
458+
functions"))) blogosfera, as clausuras (_closures_) são às vezes confundidas com funções
459+
anônimas. A confusão se deve à história paralela destes conceitos:
460460
definir funções dentro de outras funções se torna mais comum e conveniente quando
461461
existem funções anônimas.
462462
E clausuras só fazem sentido a partir do momento em que você tem funções aninhadas.
463463
Daí que muitos aprendem as duas ideias ao mesmo tempo.
464464

465465
Na verdade, uma clausura é uma função—vamos chamá-la de `f`—com um escopo
466-
estendido, incorporando variáveis acessadas no corpo de `f` que não são nem
466+
estendido, incorporando variáveis acessadas no corpo de `f` que não são
467467
variáveis globais nem variáveis locais de `f`. Tais variáveis devem vir do
468-
escopo local de uma função externa que englobe `f`.
468+
escopo local de uma função que engloba `f`.
469469

470470
Não interessa se a função é anônima ou não; o que importa é que ela pode
471471
acessar variáveis não-globais definidas fora de seu corpo.
@@ -605,17 +605,15 @@ que representa o corpo compilado da função. O <<ex_average_demo2>> demonstra i
605605
====
606606

607607
O valor de `series` é armazenado no atributo `+__closure__+` da função
608-
`avg`. Cada item em `+avg.__closure__+` corresponde a um nome em `+__code__+`.
609-
Esses itens são `cells`, e têm um atributo chamado `cell_contents`, onde o valor
610-
real pode ser encontrado. O <<ex_average_demo3>> mostra esses atributos.
608+
`avg`. Cada item em `+avg.__closure__+` corresponde a um nome em `+__code__+`,
609+
e tem um atributo chamado `cell_contents`, com o valor vinculado.
610+
Confira o <<ex_average_demo3>>:
611611

612612
[[ex_average_demo3]]
613613
.Continuando do <<ex_average_demo1>>
614614
====
615615
[source, python]
616616
----
617-
>>> avg.__code__.co_freevars
618-
('series',)
619617
>>> avg.__closure__
620618
(<cell at 0x107a44f78: list object at 0x107a91a48>,)
621619
>>> avg.__closure__[0].cell_contents
@@ -633,7 +631,7 @@ aquelas variáveis sejam parte do escopo local da função externa.((("",
633631
startref="DACclos09")))
634632

635633
[[nonlocal_sec]]
636-
=== A declaração nonlocal
634+
=== A instrução `nonlocal`
637635

638636
A((("decorators and closures", "nonlocal declarations",
639637
id="DACnonlocal09")))((("nonlocal keyword", id="nonlocal09")))((("keywords",
@@ -666,6 +664,8 @@ def make_averager():
666664

667665
Ao testar o <<ex_average_broken>>, o resultado é um erro:
668666

667+
<<<
668+
669669
[source, python]
670670
----
671671
>>> avg = make_averager()
@@ -745,6 +745,8 @@ id="DACdecimp09"))) um decorador que cronometra cada invocação da função
745745
decorada e exibe o tempo decorrido, os argumentos passados, e o resultado da
746746
chamada.
747747

748+
<<<
749+
748750
[[ex_clockdeco0]]
749751
._clockdeco0.py_: decorador que exibe o tempo de execução da função
750752
====
@@ -880,7 +882,7 @@ interessantes da biblioteca padrão são `cache`, `lru_cache` e
880882
`singledispatch`—todos do módulo `functools`. Falaremos deles a seguir.
881883

882884
[[memoization_sec]]
883-
==== Memoização com functools.cache
885+
==== Memoização com `functools.cache`
884886

885887
O((("memoization", id="memoiz09")))((("functools module", "functools.cache
886888
decorator", id="functool09"))) decorador `functools.cache` implementa
@@ -1023,7 +1025,7 @@ startref="memoiz09")))((("", startref="functool09")))
10231025

10241026

10251027
[[lru_cache_sec]]
1026-
==== Usando o lru_cache
1028+
==== Usando o `functools.lru_cache`
10271029

10281030
O((("functools module", "functools.lru_cache function"))) decorador
10291031
`functools.cache` é, na realidade, um mero invólucro em torno da antiga função
@@ -1089,7 +1091,7 @@ def costly_function(a, b):
10891091

10901092
Vamos agora examinar outro decorador poderoso: `functools.singledispatch`.
10911093

1092-
[[generic_functions_sec]]
1094+
[[single_dispatch_sec]]
10931095
==== Funções genéricas com despacho único
10941096

10951097
Imagine((("single dispatch generic functions",
@@ -1146,9 +1148,6 @@ e a sequência inteira é apresentada como uma lista HTML.
11461148
<6> Mostra `Fraction` como uma fração.
11471149
<7> Mostra `float` e `Decimal` com a fração equivalente aproximada.
11481150

1149-
[[single_dispatch_sec]]
1150-
===== Despacho único de funções
1151-
11521151
Como não temos no Python a sobrecarga de métodos ao estilo de Java, não podemos
11531152
simplesmente criar variações de `htmlize` com assinaturas diferentes para cada
11541153
tipo de dado que queremos tratar de forma distinta. Uma solução possível em
@@ -1170,7 +1169,7 @@ Se mais argumentos fossem usados para selecionar a função específica,
11701169
teríamos despacho múltiplo (_multiple dispatch_), um recurso nativo em
11711170
linguagens como Common Lisp, Julia e C#.
11721171

1173-
O <<singledispatch_ex>> mostra como funciona o despacho único.
1172+
O <<singledispatch_ex>> mostra como implementar o despacho único.
11741173

11751174
[WARNING]
11761175
====
@@ -1386,18 +1385,16 @@ revisitar o decorador `clock`, acrescentando um recurso: os usuários podem
13861385
passar uma string para formatar o relatório sobre a função cronometrada.
13871386
Veja o <<clockdeco_param_ex>>.
13881387

1389-
1390-
<<<
13911388
[NOTE]
13921389
====
1393-
13941390
Para simplificar, o <<clockdeco_param_ex>> está baseado na implementação inicial
13951391
de `clock` no <<ex_clockdeco0>>, e não na versão melhorada do
1396-
<<ex_clockdeco2>> que usa `@functools.wraps`, acrescentando assim mais uma
1397-
camada de função.
1398-
1392+
<<ex_clockdeco2>> que usa `@functools.wraps`,
1393+
evitando mais um nível de aninhamento de funções.
13991394
====
14001395

1396+
<<<
1397+
14011398
[[clockdeco_param_ex]]
14021399
.Módulo clockdeco_param.py: o decorador `clock` parametrizado
14031400
====
@@ -1572,8 +1569,8 @@ O((("decorators and closures", "further reading on"))) item #26 do livro
15721569
https://fpy.li/effectpy[_Effective Python_, 2nd ed.] (Addison-Wesley), de
15731570
Brett Slatkin, trata das melhores práticas para decoradores de função, e
15741571
recomenda sempre usar `functools.wraps`—que vimos no
1575-
<<ex_clockdeco2>>.footnote:[Como queria manter o código o mais simples possível,
1576-
não segui o excelente conselho de Slatkin em todos os exemplos.]
1572+
<<ex_clockdeco2>>. Como eu queria manter o código o mais simples possível,
1573+
não segui o excelente conselho de Slatkin em todos os exemplos.
15771574

15781575
Graham Dumpleton tem, em seu blog, uma https://fpy.li/9-5[série de posts
15791576
abrangentes] sobre técnicas para implementar decoradores bem comportados,
@@ -1586,13 +1583,13 @@ que suportam introspecção e se comportam de forma correta quando decorados
15861583
novamente, quando aplicados a métodos e quando usados como descritores de
15871584
atributos (o https://fpy.li/23[«Capítulo 23»] (vol.3) é sobre descritores).
15881585

1589-
https://fpy.li/9-8["Metaprogramming" (_Metaprogramação_)] (EN), o capítulo 9 do
1586+
https://fpy.li/9-8[_Metaprogramming_], o capítulo 9 do
15901587
_Python Cookbook_, 3ª ed. de David Beazley e Brian K. Jones (O'Reilly), tem
15911588
várias receitas ilustrando desde decoradores elementares até alguns muito
15921589
sofisticados, incluindo um que pode ser invocado como um decorador regular ou
15931590
como uma fábrica de decoradores, por exemplo, `@clock` ou `@clock()`. É a
1594-
"Recipe 9.6. Defining a Decorator That Takes an Optional Argument" (_Receita
1595-
9.6. Definindo um Decorador Que Recebe um Argumento Opcional_) desse livro de
1591+
_Recipe 9.6. Defining a Decorator That Takes an Optional Argument_
1592+
(Definindo um Decorador Que Recebe um Argumento Opcional) daquele livro de
15961593
receitas.
15971594

15981595
Michele Simionato criou https://fpy.li/9-9[_decorator_],
@@ -1626,7 +1623,7 @@ A https://fpy.li/9-14[_PEP 443_] traz a justificativa e uma descrição
16261623
detalhada do mecanismo de funções genéricas de despacho único. Um post de Guido
16271624
van Rossum de março de 2005
16281625
https://fpy.li/9-15[_Five-Minute Multimethods in Python_]
1629-
(Multi-métodos de cinco minutos em Python_), mostra os passos
1626+
(Multi-métodos de cinco minutos em Python), mostra os passos
16301627
para uma implementação de funções genéricas (também chamadas multi-métodos)
16311628
usando decoradores. O código de multi-métodos de Guido é interessante, mas é
16321629
apenas um exemplo didático. Para conhecer uma implementação de funções genéricas

vol2/cap10.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ discussion")))((("Soapbox sidebars", "design patterns"))) tem funções de
651651
primeira classe e tipos de primeira classe, e Norvig afima que esses recursos
652652
afetam 10 dos 23 padrões (slide 10 de
653653
https://fpy.li/norvigdp[_Design Patterns in Dynamic Languages_]).
654-
Na <<generic_functions_sec>>, vimos que Python também tem funções
654+
Na <<single_dispatch_sec>>, vimos que Python também tem funções
655655
genéricas de despacho único, uma forma limitada dos multi-métodos do
656656
CLOS, que Gamma et al. sugerem como uma maneira mais simples de implementar o
657657
padrão clássico Visitante (_Visitor_). Norvig, por outro lado, diz (no slide 10)

0 commit comments

Comments
 (0)