Você está na página 1de 165

Machine Translated by Google

Tutorial do Python
Versão 3.11.3

Guido van Rossum e a equipe de desenvolvimento do Python

14 de abril de 2023

E-mail da Python Software Foundation:


docs@python.org
Machine Translated by Google
Machine Translated by Google

CONTEÚDO

1 Abrindo o apetite 3

2 Usando o interpretador Python 5

2.1 Chamando o interpretador . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 5

2.1.1 Passagem de Argumento . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 6

2.1.2 Modo interativo 2.2 . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 6

O intérprete e seu ambiente . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 6

2.2.1 Codificação do Código Fonte . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 6

3 Uma introdução informal ao Python 3.1


Usando o Python como uma calculadora. . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
3.1.1 Números . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
3.1.2 Cordas . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 9
3.1.3 Listas . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 9
3.2 Primeiros passos para a programação . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 9 11 14 . 16

4 Mais ferramentas de fluxo de


. . . . . . . . . .....
controle 4.1 Instruções if . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 19 .
4.2 para Declarações . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 19 .
4.3 A Função range() 4.4 . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 19 .
Declarações break e continue e else Cláusulas em Loops . . . . . 4.5 declarações . . . . . . . . . . . . . .
de passagem . 4.6 . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
Declarações de correspondência . . .. . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
4.7 Definindo funções . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 20 21
4.8 Mais sobre como definir . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
funções 4.8.1 Valores de argumento padrão . .. .. . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8.2 Argumentos de palavra-chave . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 22
4.8.3 Parâmetros especiais . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 22 .
4.8.4 Listas de argumentos arbitrários . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 25 27
4.8.5 Desempacotando listas de .... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 27 .
argumentos 4.8.6 Expressões lambda . . .. . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 28 .
4.8.7 Strings de Documentação . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 29 .
4.8.8 Anotações de função . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 32 . 32 . 33 . 33 . 34
4.9 Intermezzo: estilo de codificação . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 34

5 Estruturas de Dados
5.1 Mais sobre listas . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 37 .
5.1.1 Usando Listas como Pilhas . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 37 .
5.1.2 Usando Listas como Filas . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 38 .
5.1.3 Abrangências de lista . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 39 . 39

eu
Machine Translated by Google

5.1.4 Abrangências de lista aninhada . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 41


5.2 A instrução del 5.3 . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 42
Tuplas e Sequências . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 42
5.4 Conjuntos . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 43
5.5 Dicionários 5.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
Técnicas de Looping . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 44 .
5.7 Mais sobre Condições . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 45 .
5.8 Comparando Sequências e Outros Tipos . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 46 47

6 Módulos
6.1 Mais sobre módulos . . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 49 .
6.1.1 Executando módulos como scripts . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 50 .
6.1.2 O caminho de pesquisa do ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 51 .
módulo 6.1.3 Arquivos Python . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 51 .
“compilados” 6.2 Módulos. . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 52 .
padrão 6.3 A função dir() . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 52 .
6.4 Pacotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 53 .
6.4.1 Importando * de um pacote . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 54 .
6.4.2 Referências intra-pacote ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 56 .
6.4.3 Pacotes em vários diretórios . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 57 . 57

7 Entrada e Saída 7.1


Formatação de Saída do Fancier . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 59 .
7.1.1 Literais de string formatados . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 59 .
7.1.2 O método String format() 7.1.3 . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 60 .
Formatação manual de strings . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 61 .
7.1.4 Formatação de strings antigas . . . . . . .
. . . . . . . . . . . . ..... . . . . . . . . . . . . . 62 .
7.2 Lendo e Escrevendo Arquivos . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 63 .
7.2.1 Métodos de Objetos de Arquivo . . . . . .. . . . . . . . . . . . ..... . . . . . . . . . . . . . 63 .
7.2.2 Salvando dados estruturados com json . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 64 . 65

8 Erros e Exceções 8.1


Erros de Sintaxe 8.2 . . . . . . . . . . . ..... .. . . . . . . . . . . ..... . . . . . . . . . . . . . 67 .
Exceções . . . . . . . . . . . . ..... .. . . . . . . . . . . ..... . . . . . . . . . . . . . 67 .
8.3 Manipulando Exceções . . . . . . . ..... .. . . . . . . . . . . ..... . . . . . . . . . . . . . 67 .
8.4 Gerando Exceções . . . . . . . . ..... .. . . . . . . . . . . ..... . . . . . . . . . . . . . 68 .
8.5 Encadeamento de Exceções . . . . . . . . ..... .. . . . . . . . . . . ..... . . . . . . . . . . . . . .
8.6 Exceções Definidas pelo Usuário . . . . . ..... .. . . . . . . . . . . ..... . . . . . . . . . . . . . . 70
8.7 Definindo ações de limpeza . . . . ..... .. . . . . . . . . . . ..... . . . . . . . . . . . . . . 71
8.8 Ações de limpeza predefinidas . . . ..... .. . . . . . . . . . . ..... . . . . . . . . . . . . . . 72
8.9 Gerando e tratando várias exceções não relacionadas . . . . . . . ..... . . . . . . . . . . . . . . 72
8.10 Enriquecendo exceções com notas . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 74 74 . 75

9 aulas 77
9.1 Uma palavra sobre nomes e objetos . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
9.2 Escopos e Namespaces do Python . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 77 .
9.2.1 Exemplo de Escopos e Namespaces . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 78 .
9.3 Uma primeira olhada nas classes . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 79 . 80
Sintaxe de Definição de ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 80
. . . .
Classe . 9.3.1 9.3.2 Objetos de Classe .. . .... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 80 .
9.3.3 Objetos de Instância . . . . . . .... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 81 .
9.3.4 Objetos de método . . . . . . .... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 82 .
9.3.5 Variáveis de Classe e Instância . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 82 .
9.4 Observações aleatórias . . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 83 .
9.5 Herança . . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 85

ii
Machine Translated by Google

9.5.1 Herança Múltipla 9.6 . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 85 .


Variáveis Privadas . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 86 .
9.7 Odds and Ends . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 87 .
9.8 Iteradores . . . . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 87 .
9.9 Geradores . . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 89 .
9.10 Expressões do Gerador . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 89

10 Breve tour pela biblioteca padrão


10.1 Interface do sistema . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 91 .
operacional 10.2 Curingas. de. .arquivo
. . . .. . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 91 .
10.3 Argumentos de linha de comando . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 91 .
10.4 Redirecionamento de saída de erro e finalização do programa . . . . . . . . ..... . . . . . . . . . . . . . 92 .
.
10.5 Correspondência de padrão de string . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 92 .
10.6 Matemática . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 92 .
10.7 Acesso à Internet . . . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 93 .
10.8 Datas e Horários . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 93 .
10.9 Compressão de Dados . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 94 .
10.10 Medição de desempenho . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 94 .
.
10.11 Controle de qualidade . . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 95 .
10.12 Baterias Incluídas . . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 95 . 96

11 Breve Tour pela Biblioteca Padrão — Parte II


11.1 Formatação de Saída . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 97 .
11.2 Modelos . . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 97 .
11.3 Trabalhando com layouts de registro de dados binários . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 98 .
11.4 Multi-threading . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 99 .
11.5 Registro . . . . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 99 .
11.6 Referências fracas . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 100 .
11.7 Ferramentas para trabalhar com . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 101 .
listas 11.8 Aritmética de ponto flutuante decimal. . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 101 . 102

12 Ambientes Virtuais e Pacotes


12.1 Introdução . . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 105 .
12.2 Criando Ambientes Virtuais . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 105 .
12.3 Gerenciando pacotes com pip . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 105 . 106

13 E agora? 109

14 Edição de entrada interativa e substituição de 111


. . .. . .. .. . . . . . . . . . . . .
histórico 14.1 Conclusão de guias e edição de histórico . . . . . . . . . . . . . . 111
14.2 Alternativas ao Interpretador Interativo . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . 111

15 Aritmética de Ponto Flutuante: Problemas e Limitações


15.1 Erro de Representação . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 113 . 116

16 Apêndice
16.1 Modo interativo . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 119 .
16.1.1 Tratamento de erros . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 119 .
16.1.2 Scripts Python executáveis . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . . 119 .
16.1.3 O arquivo de inicialização .... . . . . . . . . . . . . ..... . . . . . . . . . . . . . 119 .
....
interativo 16.1.4 Os módulos de personalização . . . . . . . . . . . . ..... . . . . . . . . . . . . . 120 . 120

Um glossário 121

B Sobre estes documentos 135

iii
Machine Translated by Google

B.1 Contribuidores para a documentação do Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

C Histórico e Licença 137


C.1 Histórico do software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
C.2 Termos e condições para acessar ou usar o Python . . . ..... . . . . . . . . . . . . . . 138
C.2.1 CONTRATO DE LICENÇA PSF PARA PYTHON 3.11.3 . . 138 C.2.2 CONTRATO..... .DE
. .LICENÇA
. . . . BEOPEN.COM
. . . . . .
PARA PYTHON 2.0 . . . 139 C.2.3 CONTRATO DE LICENÇA CNRI PARA PYTHON 1.6.1 . . . . 140
. . C.2.4
. . . CONTRATO
. . . . . DE
LICENÇA CWI PARA PYTHON 0.9.0 ATÉ 1.2 . 141 C.2.5 LICENÇA BSD DE.CLÁUSULA.... . .ZERO
. . . PARA
. . . CÓDIGO
. . . . .NO
PYTHON 3.11.3 DOCUMENTAÇÃO141 C.3 Licenças e Reconhecimentos para Software Incorporado . . . . .. 142
. . 142
. . . .143
. .
143 144 144 . 145 . 145 . 146 . 146 147 147 . 148 . 150 . 151 . 151 . 152 . 152 . 153 . 154
. . . ..... . . . . . . . . . . . . . .
C.3.1 Mersenne Twister . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
C.3.2 Soquetes . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.3 Serviços de soquete assíncronos . . . . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.4 Gestão de cookies . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
C.3.5 Rastreamento de execução . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
C.3.6 Funções UUencode e UUdecode C.3.7 . . . . . . . . . . . . ..... . . . . . . . . . . . . .
Chamadas de Procedimento Remoto XML . . . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.8 test_epoll . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.9 Selecione kqueue . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.10 SipHash24 . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
C.3.11 strtod e dtoa . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . . .
C.3.12 OpenSSL . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.13 expatriado . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.14 libffi . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.15 zlib . . . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.16 cfuhash . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.17 libmpdec . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C.3.18 Conjunto de testes W3C . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .
C14N C.3.19 Audioop . . . . . . . . . ..... . . . . . . . . . . . . ..... . . . . . . . . . . . . .

D direitos autorais 155

Índice 157

4
Machine Translated by Google

Tutorial do Python, versão 3.11.3

Python é uma linguagem de programação poderosa e fácil de aprender. Possui estruturas de dados eficientes de alto nível e uma abordagem simples,
mas eficaz, para programação orientada a objetos. A sintaxe elegante e a digitação dinâmica do Python, juntamente com sua natureza interpretada,
o tornam uma linguagem ideal para scripts e desenvolvimento rápido de aplicativos em muitas áreas na maioria das plataformas.

O interpretador Python e a extensa biblioteca padrão estão disponíveis gratuitamente em formato fonte ou binário para todas as principais plataformas
no site Python, https://www.python.org/, e podem ser distribuídos livremente. O mesmo site também contém distribuições e ponteiros para muitos
módulos, programas e ferramentas Python gratuitos de terceiros, além de documentação adicional.

O interpretador Python é facilmente estendido com novas funções e tipos de dados implementados em C ou C++ (ou outras linguagens que podem
ser chamadas de C). O Python também é adequado como uma linguagem de extensão para aplicativos personalizáveis.

Este tutorial apresenta ao leitor informalmente os conceitos e recursos básicos da linguagem e do sistema Python. É útil ter um interpretador Python
à mão para experiência prática, mas todos os exemplos são independentes, portanto, o tutorial também pode ser lido off-line.

Para obter uma descrição de objetos e módulos padrão, consulte library-index. o índice de referência fornece uma definição mais formal da linguagem.
Para escrever extensões em C ou C++, leia extending-index e c-api-index. Existem também vários livros que cobrem o Python em profundidade.

Este tutorial não pretende ser abrangente e cobrir todos os recursos, ou mesmo todos os recursos comumente usados.
Em vez disso, ele apresenta muitos dos recursos mais notáveis do Python e lhe dará uma boa ideia do sabor e do estilo da linguagem. Depois de lê-
lo, você será capaz de ler e escrever módulos e programas Python e estará pronto para aprender mais sobre os vários módulos da biblioteca Python
descritos em library-index.

Também vale a pena consultar o Glossário .

CONTEÚDO 1
Machine Translated by Google

Tutorial do Python, versão 3.11.3

2 CONTEÚDO
Machine Translated by Google

CAPÍTULO

UM

ATIVANDO SEU APETITE

Se você trabalha muito em computadores, acaba descobrindo que há alguma tarefa que gostaria de automatizar. Por exemplo, você pode querer
executar uma pesquisa e substituição em um grande número de arquivos de texto ou renomear e reorganizar vários arquivos de fotos de maneira
complicada. Talvez você queira escrever um pequeno banco de dados personalizado, um aplicativo GUI especializado ou um jogo simples.

Se você é um desenvolvedor de software profissional, pode ter que trabalhar com várias bibliotecas C/C++/Java, mas descobrir que o ciclo normal
de gravação/compilação/teste/recompilação é muito lento. Talvez você esteja escrevendo um conjunto de testes para tal biblioteca e ache que
escrever o código de teste é uma tarefa tediosa. Ou talvez você tenha escrito um programa que poderia usar uma linguagem de extensão e não
deseja projetar e implementar uma linguagem totalmente nova para seu aplicativo.

Python é a linguagem certa para você.

Você poderia escrever um script de shell Unix ou arquivos em lote do Windows para algumas dessas tarefas, mas os scripts de shell são melhores
para mover arquivos e alterar dados de texto, não adequados para aplicativos ou jogos GUI. Você pode escrever um programa C/C++/Java, mas
pode levar muito tempo de desenvolvimento para obter até mesmo um programa de primeiro rascunho. O Python é mais simples de usar, está
disponível nos sistemas operacionais Windows, macOS e Unix e ajudará você a realizar o trabalho com mais rapidez.

Python é simples de usar, mas é uma linguagem de programação real, oferecendo muito mais estrutura e suporte para programas grandes do que
scripts de shell ou arquivos em lote podem oferecer. Por outro lado, Python também oferece muito mais verificação de erros do que C e, sendo uma
linguagem de alto nível, possui tipos de dados de alto nível incorporados, como arrays flexíveis e dicionários. Por causa de seus tipos de dados mais
gerais, Python é aplicável a um domínio de problema muito maior do que Awk ou mesmo Perl, mas muitas coisas são pelo menos tão fáceis em
Python quanto nessas linguagens.

Python permite que você divida seu programa em módulos que podem ser reutilizados em outros programas Python. Ele vem com uma grande
coleção de módulos padrão que você pode usar como base para seus programas — ou como exemplos para começar a aprender a programar em
Python. Alguns desses módulos fornecem itens como E/S de arquivo, chamadas de sistema, soquetes e até mesmo interfaces para kits de
ferramentas de interface gráfica do usuário como Tk.

Python é uma linguagem interpretada, que pode economizar um tempo considerável durante o desenvolvimento do programa porque nenhuma
compilação e vinculação são necessárias. O interpretador pode ser usado interativamente, o que torna fácil experimentar os recursos da linguagem,
escrever programas descartáveis ou testar funções durante o desenvolvimento de programas de baixo para cima. É também uma calculadora de
mesa útil.

O Python permite que os programas sejam escritos de forma compacta e legível. Programas escritos em Python são normalmente muito mais curtos
do que programas equivalentes em C, C++ ou Java, por vários motivos:

• os tipos de dados de alto nível permitem expressar operações complexas em uma única instrução;

• o agrupamento de instruções é feito por recuo em vez de colchetes iniciais e finais;

• nenhuma declaração de variável ou argumento é necessária.

O Python é extensível: se você sabe programar em C, é fácil adicionar uma nova função ou módulo interno ao interpretador, seja para executar
operações críticas na velocidade máxima ou para vincular programas Python a bibliotecas que podem estar disponíveis apenas em formato binário
(como uma biblioteca gráfica específica do fornecedor). Quando estiver realmente viciado, você pode vincular o interpretador Python a um aplicativo
escrito em C e usá-lo como uma extensão ou linguagem de comando para esse aplicativo.

3
Machine Translated by Google

Tutorial do Python, versão 3.11.3

A propósito, a linguagem leva o nome do programa da BBC “Monty Python's Flying Circus” e não tem nada a ver com répteis.
Fazer referências a esquetes do Monty Python na documentação não é apenas permitido, é encorajado!

Agora que você está todo empolgado com o Python, você vai querer examiná-lo com mais detalhes. Como a melhor maneira de aprender
uma linguagem é usando-a, o tutorial convida você a brincar com o interpretador Python enquanto lê.

No próximo capítulo, a mecânica de uso do interpretador é explicada. Esta é uma informação um tanto mundana, mas essencial para
experimentar os exemplos mostrados posteriormente.

O restante do tutorial apresenta vários recursos da linguagem e do sistema Python por meio de exemplos, começando com expressões
simples, declarações e tipos de dados, passando por funções e módulos e, finalmente, abordando conceitos avançados como exceções e
classes definidas pelo usuário.

4 Capítulo 1. Aguçando seu apetite


Machine Translated by Google

CAPÍTULO

DOIS

USANDO O INTERPRETADOR PYTHON

2.1 Chamando o interpretador

O interpretador Python geralmente é instalado como /usr/local/bin/python3.11 nas máquinas em que está disponível; colocar /usr/local/bin no
caminho de pesquisa do seu shell Unix torna possível iniciá-lo digitando o comando:

python3.11

para o shell.1 Como a escolha do diretório onde reside o interpretador é uma opção de instalação, outros locais são possíveis; verifique com seu
guru Python local ou administrador do sistema. (Por exemplo, /usr/local/python é um local alternativo popular.)

Em máquinas Windows nas quais você instalou o Python da Microsoft Store, o comando python3.11 estará disponível. Se você tiver o iniciador
py.exe instalado, poderá usar o comando py. Consulte setting-envvars para outras maneiras de iniciar o Python.

Digitar um caractere de fim de arquivo (Control-D no Unix, Control-Z no Windows) no prompt principal faz com que o interpretador saia com um
status de saída zero. Se isso não funcionar, você pode sair do interpretador digitando o seguinte comando: quit().

Os recursos de edição de linha do interpretador incluem edição interativa, substituição de histórico e conclusão de código em sistemas que suportam
o GNU Readline biblioteca. Talvez a verificação mais rápida para ver se a edição de linha de comando é suportada é digitar Control-P no primeiro
prompt do Python que você obtiver. Se emitir um bipe, você tem edição de linha de comando; consulte o Apêndice Edição de entrada interativa e
substituição de histórico para obter uma introdução às chaves. Se nada acontecer, ou se ^P for repetido, a edição da linha de comando não estará
disponível; você só poderá usar backspace para remover caracteres da linha atual.

O interpretador funciona como o shell do Unix: quando chamado com entrada padrão conectada a um dispositivo tty, ele lê e executa comandos
interativamente; quando chamado com um argumento de nome de arquivo ou com um arquivo como entrada padrão, ele lê e executa um script
desse arquivo.

Uma segunda maneira de iniciar o interpretador é python -c command [arg] ..., que executa a(s) instrução(ões) no comando, de forma análoga à
opção -c do shell. Como as instruções do Python geralmente contêm espaços ou outros caracteres especiais para o shell, geralmente é
recomendável citar o comando em sua totalidade.

Alguns módulos Python também são úteis como scripts. Eles podem ser invocados usando python -m module [arg] ..., que executa o arquivo de
origem para o módulo como se você tivesse soletrado seu nome completo na linha de comando.

Quando um arquivo de script é usado, às vezes é útil poder executar o script e entrar no modo interativo posteriormente. Isso pode ser feito
passando -i antes do script.

Todas as opções de linha de comando são descritas em using-on-general.

1 No Unix, o interpretador Python 3.x por padrão não é instalado com o executável chamado python, para que não entre em conflito com um

executável Python 2.x instalado.

5
Machine Translated by Google

Tutorial do Python, versão 3.11.3

2.1.1 Passagem de Argumento

Quando conhecido pelo interpretador, o nome do script e os argumentos adicionais subsequentes são transformados em uma lista de strings e atribuídos
à variável argv no módulo sys. Você pode acessar essa lista executando import sys. O comprimento da lista é pelo menos um; quando nenhum script e
nenhum argumento é fornecido, sys.argv[0] é uma string vazia. Quando o nome do script é fornecido como '-' (significando entrada padrão), sys.argv[0] é
definido como '-'. Quando o comando -c é usado, sys.argv[0] é definido como '-c'. Quando o módulo -m é usado, sys.argv[0] é definido como o nome
completo do módulo localizado. As opções encontradas após o comando -c ou o módulo -m não são consumidas pelo processamento de opções do
interpretador Python, mas deixadas em sys.argv para o comando ou módulo manipular.

2.1.2 Modo interativo

Quando os comandos são lidos de um tty, diz-se que o interpretador está no modo interativo. Nesse modo, ele solicita o próximo comando com o prompt
principal, geralmente três sinais de maior (>>>); para linhas de continuação, ele solicita com o prompt secundário, por padrão, três pontos (...). O
interpretador imprime uma mensagem de boas-vindas informando seu número de versão e um aviso de direitos autorais antes de imprimir o primeiro
prompt:

$ python3.11
Python 3.11 (padrão, 4 de abril de 2021, 09:25:04)
[GCC 10.2.0] no linux Digite
"ajuda", "copyright", "créditos" ou "licença" para obter mais informações.
>>>

As linhas de continuação são necessárias ao inserir uma construção de várias linhas. Como exemplo, dê uma olhada nesta instrução if:

>>> the_world_is_flat = Verdadeiro


>>> se the_world_is_flat:
... print(" Cuidado para não cair!")
...
Cuidado para não cair!

Para saber mais sobre o modo interativo, consulte Modo interativo.

2.2 O intérprete e seu ambiente

2.2.1 Codificação do Código Fonte

Por padrão, os arquivos de origem do Python são tratados como codificados em UTF-8. Nessa codificação, os caracteres da maioria dos idiomas do
mundo podem ser usados simultaneamente em strings literais, identificadores e comentários — embora a biblioteca padrão use apenas caracteres ASCII
para identificadores, uma convenção que qualquer código portátil deve seguir. Para exibir todos esses caracteres corretamente, seu editor deve reconhecer
que o arquivo é UTF-8 e deve usar uma fonte que suporte todos os caracteres do arquivo.

Para declarar uma codificação diferente da padrão, uma linha de comentário especial deve ser adicionada como a primeira linha do arquivo. A sintaxe é a
seguinte:

# -*- codificação: codificação -*-

onde a codificação é um dos codecs válidos suportados pelo Python.

Por exemplo, para declarar que a codificação Windows-1252 deve ser usada, a primeira linha do arquivo de código-fonte deve ser:

6 Capítulo 2. Usando o interpretador Python


Machine Translated by Google

Tutorial do Python, versão 3.11.3

# -*- codificação: cp1252 -*-

Uma exceção à regra da primeira linha é quando o código-fonte começa com uma linha “shebang” do UNIX. Nesse caso, a declaração
de codificação deve ser adicionada como a segunda linha do arquivo. Por exemplo:

#!/usr/bin/env python3 # -*-


codificação: cp1252 -*-

2.2. O intérprete e seu ambiente 7


Machine Translated by Google

Tutorial do Python, versão 3.11.3

8 Capítulo 2. Usando o interpretador Python


Machine Translated by Google

CAPÍTULO

TRÊS

UMA INTRODUÇÃO INFORMAL AO PYTHON

Nos exemplos a seguir, entrada e saída são diferenciadas pela presença ou ausência de prompts (»> e …): para repetir o exemplo, você deve
digitar tudo após o prompt, quando o prompt aparecer; as linhas que não começam com um prompt são geradas pelo interpretador. Observe
que um prompt secundário em uma linha isolada em um exemplo significa que você deve digitar uma linha em branco; isso é usado para
finalizar um comando de várias linhas.

Muitos dos exemplos neste manual, mesmo aqueles inseridos no prompt interativo, incluem comentários. Os comentários em Python começam
com o caractere hash, #, e se estendem até o final da linha física. Um comentário pode aparecer no início de uma linha ou após um espaço
em branco ou código, mas não dentro de uma string literal. Um caractere hash dentro de uma string literal é apenas um caractere hash. Como
os comentários são para esclarecer o código e não são interpretados pelo Python, eles podem ser omitidos ao digitar exemplos.

Alguns exemplos:

# esse é o primeiro comentário


spam = 1 # e este é o segundo comentário # ... e agora um terceiro! text
= "# Este não é um comentário porque
está entre aspas."

3.1 Usando o Python como uma calculadora

Vamos tentar alguns comandos simples do Python. Inicie o interpretador e aguarde o prompt principal, >>>. (Não deve demorar.)

3.1.1 Números

O interpretador funciona como uma calculadora simples: você pode digitar uma expressão nela e ela escreverá o valor. A sintaxe da expressão
é direta: os operadores +, -, * e / funcionam exatamente como na maioria das outras linguagens (por exemplo, Pascal ou C); parênteses (())
podem ser usados para agrupamento. Por exemplo:

>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4 5,0

>>> 8/5 # divisão sempre retorna um número de ponto flutuante 1.6

Os números inteiros (eg 2, 4, 20) são do tipo int, os com parte fracionária (eg 5.0, 1.6) são do tipo float.
Veremos mais sobre tipos numéricos posteriormente no tutorial.

9
Machine Translated by Google

Tutorial do Python, versão 3.11.3

A divisão (/) sempre retorna um float. Para fazer a divisão do piso e obter um resultado inteiro, você pode usar o operador //; para calcular o
restante você pode usar %:

>>> 17/3 # divisão clássica retorna um float


5.666666666666667
>>>
>>> 17 // 3 # divisão de andares descarta a parte fracionária
5
>>> 17 % 3 # o operador % retorna o restante da divisão
2
>>> 5 * 3 + 2 # quociente mínimo * divisor + resto
17

Com Python, é possível usar o ** operador para calcular potências1 :

>>> 5 ** 2 # 5 ao quadrado 25

>>> 2 ** 7 # 2 elevado a 7 128

O sinal de igual (=) é usado para atribuir um valor a uma variável. Posteriormente, nenhum resultado é exibido antes do próximo prompt
interativo:

>>> largura = 20

>>> altura = 5 * 9 >>> largura *


altura 900

Se uma variável não estiver “definida” (atribuída a um valor), tentar usá-la dará um erro:

>>> n # tente acessar uma variável indefinida


Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
NameError: nome 'n' não está definido

Há suporte total para ponto flutuante; operadores com operandos de tipo misto convertem o operando inteiro em ponto flutuante:

>>> 4 * 3,75 - 1
14,0

No modo interativo, a última expressão impressa é atribuída à variável como uma _. Isso significa que quando você está usando Python
calculadora de mesa, é um pouco mais fácil continuar os cálculos, por exemplo:

>>> imposto = 12,5 / 100


>>> preço = 100,50 >>> preço *
imposto 12,5625

>>> preço + _
113.0625
>>> round(_, 2) 113.06

Essa variável deve ser tratada como somente leitura pelo usuário. Não atribua explicitamente um valor a ela — você criaria uma variável local
independente com o mesmo nome, mascarando a variável interna com seu comportamento mágico.

1 -, -3**2 será interpretado como -(3**2) e, portanto, resultará em -9. Para evitar isso e obter 9, você pode usar
Como ** tem precedência maior
que (-3)**2.

10 Capítulo 3. Uma introdução informal ao Python


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Além de int e float, o Python suporta outros tipos de números, como Decimal e Fraction. Python também possui suporte interno para números
complexos e usa o sufixo j ou J para indicar a parte imaginária (por exemplo, 3+5j).

3.1.2 Cordas
Além de números, Python também pode manipular strings, que podem ser expressas de várias maneiras. Eles podem ser colocados entre aspas
simples ('...') ou aspas duplas ("...") com o mesmo resultado2 . \ pode ser usado para escapar de aspas:

>>> 'spam eggs' # aspas simples 'spam eggs' >>>


'doesn\'t' # use \'
para escapar das aspas simples... "doesn't" >>> "doesn't" # . ..ou use aspas duplas

"não"
>>> '"Sim", eles disseram.'
''Sim', eles disseram.'
>>> "\"Sim,\" eles disseram."
''Sim', eles disseram.'
>>> '"Não é," eles disseram.'
''Não é', eles disseram.'

No interpretador interativo, a string de saída é colocada entre aspas e os caracteres especiais são escapados com barras invertidas.
Embora às vezes isso possa parecer diferente da entrada (as aspas podem mudar), as duas strings são equivalentes. A string é colocada entre
aspas duplas se a string contiver uma aspa simples e não houver aspas duplas, caso contrário, ela será colocada entre aspas simples. A função
print() produz uma saída mais legível, omitindo as aspas delimitadoras e imprimindo caracteres de escape e especiais:

>>> '"Não é," eles disseram.'


''Não é', eles disseram.' >>>
print('"Não é," eles disseram.')
"Não é", eles disseram. >>> s
= 'Primeira linha.\nSegunda linha.' # \n significa nova linha >>> s # sem print(), \n é incluído
na saída 'Primeira linha.\nSegunda linha.' >>> print(s) # com print(), \n produz uma nova
linha

Primeira linha.
Segunda linha.

Se você não quiser que os caracteres precedidos por \ sejam interpretados como caracteres especiais, você pode usar strings brutas adicionando
um r antes da primeira aspa:

>>> print('C:\some\name') # aqui \n significa nova linha!


C:\alguns
ame
>>> print(r'C:\some\name') # observe o r antes das aspas
C:\algum\nome

Há um aspecto sutil nas strings brutas: uma string bruta não pode terminar em um número ímpar de \ caracteres; consulte a entrada do FAQ para
obter mais informações e soluções alternativas.

Os literais de string podem abranger várias linhas. Uma maneira é usar aspas triplas: """...""" ou '''...'''. Fim de linhas são incluídos automaticamente
na string, mas é possível evitar isso adicionando um \ no final da linha. O seguinte exemplo:

2
Ao contrário de outros idiomas, caracteres especiais como \n têm o mesmo significado com aspas simples ('...') e duplas ("..."). A única
diferença entre os dois é que dentro de aspas simples não precisa escapar " (mas tem que escapar \') e vice-versa.

3.1. Usando Python como Calculadora 11


Machine Translated by Google

Tutorial do Python, versão 3.11.3

imprimir("""\
Uso: coisinha [OPÇÕES]
-h Exibir esta mensagem de uso
-H nome do host Nome do host para se conectar

""")

produz a seguinte saída (observe que a nova linha inicial não está incluída):

Uso: thingy [OPÇÕES] -h


Exibir esta mensagem de uso
-H nome do host Nome do host para se conectar

Strings podem ser concatenadas (coladas) com o operador + e repetidas com *:

>>> # 3 vezes 'un', seguido de 'ium' >>> 3 * 'un' + 'ium'

'ununúnio'

Duas ou mais strings literais (ou seja, aquelas entre aspas) próximas umas das outras são concatenadas automaticamente.

>>> 'Py' 'thon'


'Pitão'

Esse recurso é particularmente útil quando você deseja quebrar strings longas:

>>> text = ('Coloque várias strings entre parênteses '


... 'para tê-los unidos.')
>>> texto
'Coloque várias strings entre parênteses para uni-las.'

Isso funciona apenas com dois literais, não com variáveis ou expressões:

>>> prefix = 'Py' >>> prefix


'thon' # não pode concatenar uma variável e uma string literal
Arquivo "<stdin>", linha 1 prefixo 'thon'

^^^^^^

SyntaxError: sintaxe inválida >>> ('un' * 3) 'ium'

Arquivo "<stdin>", linha 1


('un' * 3) 'ium'
^^^^^

SyntaxError: sintaxe inválida

Se você deseja concatenar variáveis ou uma variável e um literal, use +:

>>> prefixo + 'thon'


'Pitão'

Strings podem ser indexadas (subscritas), com o primeiro caractere tendo índice 0. Não há nenhum tipo de caractere separado; um caractere
é simplesmente uma string de tamanho um:

>>> palavra = 'Python' >>>


palavra[0] # caractere na posição 0
'P'
>>> palavra[5] # caractere na posição 5 'n'

12 Capítulo 3. Uma introdução informal ao Python


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Os índices também podem ser números negativos, para começar a contar a partir da direita:

>>> palavra[-1] # último caractere


'n'
>>> palavra[-2] # penúltimo caractere
'o'
>>> palavra[-6]
'P'

Observe que, como -0 é igual a 0, os índices negativos começam em -1.

Além da indexação, o fatiamento também é suportado. Enquanto a indexação é usada para obter caracteres individuais, o fatiamento
permite obter substring:

>>> palavra[0:2] # caracteres da posição 0 (incluída) a 2 (excluída)


'Py'
>>> word[2:5] # caracteres da posição 2 (incluída) a 5 (excluída) 'tho'

Os índices de fatia têm padrões úteis; um primeiro índice omitido assume como padrão zero, um segundo índice omitido assume como padrão o tamanho da
string que está sendo fatiada.

>>> word[:2] # caractere do início até a posição 2 (excluído)


'Py'
>>> palavra[4:] # caracteres da posição 4 (incluída) até o final
'sobre'
>>> word[-2:] # caracteres do penúltimo (incluído) até o final
'sobre'

Observe como o início é sempre incluído e o final sempre excluído. Isso garante que s[:i] + s[i:] seja sempre igual a s:

>>> palavra[:2] + palavra[2:]


'Python' >>>
palavra[:4] + palavra[4:]
'Pitão'

Uma maneira de lembrar como as fatias funcionam é pensar nos índices como apontando entre os caracteres, com a borda esquerda do
primeiro caractere numerada como 0. Então, a borda direita do último caractere de uma string de n caracteres tem o índice n, por exemplo:

+---+---+---+---+---+---+
| P | y | t | h | o | n | +---+---+---+---+---+---+

0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1

A primeira linha de números dá a posição dos índices 0…6 na string; a segunda linha fornece os índices negativos correspondentes. A
fatia de i a j consiste em todos os caracteres entre as arestas i e j, respectivamente.

Para índices não negativos, o comprimento de uma fatia é a diferença dos índices, se ambos estiverem dentro dos limites. Por exemplo,
o comprimento de word[1:3] é 2.

A tentativa de usar um índice muito grande resultará em um erro:

>>> palavra[42] # a palavra só tem 6 caracteres


Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
IndexError: índice de string fora do intervalo

3.1. Usando Python como Calculadora 13


Machine Translated by Google

Tutorial do Python, versão 3.11.3

No entanto, os índices de fatia fora do intervalo são tratados normalmente quando usados para fatiar:

>>> palavra[4:42] 'on'

>>> palavra[42:]
''

As strings do Python não podem ser alteradas — elas são imutáveis. Portanto, atribuir a uma posição indexada na string resulta em um erro:

>>> palavra[0] = 'J'


Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
TypeError: objeto 'str' não suporta atribuição de item >>> palavra[2:] = 'py'

Traceback (última chamada mais recente):


Arquivo "<stdin>", linha 1, em <module>
TypeError: objeto 'str' não suporta atribuição de item

Se você precisar de uma string diferente, crie uma nova:

>>> 'J' + palavra[1:]


'Jython' >>>
palavra[:2] + 'py'
'Pypy'

A função interna len() retorna o comprimento de uma string:

>>> s = 'supercalifragilisticexpialidocious' >>> len(s) 34

Veja também:

textseq Strings são exemplos de tipos de sequência e suportam as operações comuns suportadas por tais tipos.

string-methods Strings suportam um grande número de métodos para transformações e buscas básicas.

f-strings Literais de cadeia de caracteres que possuem expressões incorporadas.

formatstrings Informações sobre formatação de strings com str.format().

old-string-formatting As antigas operações de formatação invocadas quando as strings são o operando esquerdo do operador % são
descritos com mais detalhes aqui.

3.1.3 Listas

Python conhece vários tipos de dados compostos , usados para agrupar outros valores. A mais versátil é a lista, que pode ser escrita como uma lista
de valores separados por vírgulas (itens) entre colchetes. As listas podem conter itens de tipos diferentes, mas geralmente todos os itens têm o mesmo
tipo.

>>> quadrados = [1, 4, 9, 16, 25] >>> quadrados [1,


4, 9, 16, 25]

Assim como as strings (e todos os outros tipos de sequência integrados ), as listas podem ser indexadas e segmentadas:

14 Capítulo 3. Uma introdução informal ao Python


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> squares[0] # indexação retorna o item 1

>>> squares[-1] 25 >>>

squares[-3:] # fatiar retorna uma nova lista [9, 16, 25]

Todas as operações de fatia retornam uma nova lista contendo os elementos solicitados. Isso significa que a seguinte fatia retorna uma cópia rasa da
lista:

>>> quadrados[:] [1,


4, 9, 16, 25]

As listas também suportam operações como concatenação:

>>> quadrados + [36, 49, 64, 81, 100] [1, 4, 9, 16, 25, 36,
49, 64, 81, 100]

Ao contrário das strings, que são imutáveis, as listas são do tipo mutável , ou seja, é possível alterar seu conteúdo:

>>> cubes = [1, 8, 27, 65, 125] # algo está errado aqui >>> 4 ** 3 # o cubo de 4 é 64, não 65! 64

>>> cubes[3] = 64 # substitua o valor errado >>> cubes

[1, 8, 27, 64, 125]

Você também pode adicionar novos itens no final da lista, usando o método append() (veremos mais sobre métodos mais adiante):

>>> cubes.append(216) # soma o cubo de 6 >>> cubes.append(7 **


3) # e o cubo de 7 >>> cubes

[1, 8, 27, 64, 125, 216, 343]

A atribuição de fatias também é possível, e isso pode até alterar o tamanho da lista ou limpá-la totalmente:

>>> letras = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] >>> letras

['a', 'b', 'c', 'd', 'e', 'f', 'g'] >>> # substitua alguns valores
>>> letras [ 2 :5] = ['C' , 'D', 'E'] >>> letras

['a', 'b', 'C', 'D', 'E', 'f', 'g'] >>> # agora remova-os

>>> letras[2:5] = [] >>> letras

['a', 'b', 'f', 'g'] >>> # limpa a lista


substituindo todos os elementos por uma lista vazia >>> letras[:] = [] >>> letras

[]

A função interna len() também se aplica a listas:

3.1. Usando Python como Calculadora 15


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> letras = ['a', 'b', 'c', 'd'] >>> len(letras) 4

É possível aninhar listas (criar listas contendo outras listas), por exemplo:

>>> a = ['a', 'b', 'c'] >>> n = [1, 2, 3]

>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]] >>> x[0] ['a', 'b', 'c'] >>>
x[0] [1] 'b'

3.2 Primeiros passos para a programação

Claro, podemos usar o Python para tarefas mais complicadas do que somar dois mais dois. Por exemplo, podemos escrever uma subsequência
inicial da série de Fibonacci do seguinte modo:

>>> # Série de Fibonacci:


... # a soma de dois elementos define o próximo
... a, b = 0, 1 >>>
enquanto a < 10:
... print(a) a, b
... = b, a+b
...
0
1
1
2
3
5
8

Este exemplo apresenta vários novos recursos.

• A primeira linha contém uma atribuição múltipla: as variáveis a e b obtêm simultaneamente os novos valores 0 e 1. Na última linha, isso é
usado novamente, demonstrando que as expressões do lado direito são todas avaliadas antes de qualquer uma das atribuições acontecem.
As expressões do lado direito são avaliadas da esquerda para a direita.

• O loop while é executado enquanto a condição (aqui: a < 10) permanecer verdadeira. Em Python, como em C, qualquer valor inteiro diferente
de zero é verdadeiro; zero é falso. A condição também pode ser uma string ou um valor de lista, na verdade, qualquer sequência; qualquer
coisa com comprimento diferente de zero é verdadeira, sequências vazias são falsas. O teste usado no exemplo é uma comparação simples.
Os operadores de comparação padrão são escritos da mesma forma que em C: < (menor que), > (maior que), == (igual a), <= (menor ou
igual a), >= (maior ou igual a) e != (diferente de).

• O corpo do loop é recuado: recuo é a maneira do Python agrupar instruções. No prompt interativo, você deve digitar uma tabulação ou
espaço(s) para cada linha recuada. Na prática, você preparará entradas mais complicadas para Python com um editor de texto; todos os
editores de texto decentes têm um recurso de recuo automático. Quando uma instrução composta é inserida interativamente, ela deve ser
seguida por uma linha em branco para indicar a conclusão (já que o analisador não pode adivinhar quando você digitou a última linha).
Observe que cada linha dentro de um bloco básico deve ter o mesmo recuo.

• A função print() escreve o valor do(s) argumento(s) que recebe. Ele difere de apenas escrever a expressão que você deseja escrever (como
fizemos anteriormente nos exemplos da calculadora) na forma como lida com vários argumentos, flutuando

16 Capítulo 3. Uma introdução informal ao Python


Machine Translated by Google

Tutorial do Python, versão 3.11.3

quantidades de pontos e strings. As strings são impressas sem aspas e um espaço é inserido entre os itens, para que você possa formatar as
coisas de maneira adequada, assim:

>>> i = 256*256
>>> print('O valor de i é', i)
O valor de i é 65536

O argumento de palavra-chave end pode ser usado para evitar a nova linha após a saída ou terminar a saída com uma string
diferente:

>>> a, b = 0, 1 >>>
enquanto a < 1000:
... print(a, end=',') a, b = b,
... a+b
...
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

3.2. Primeiros passos para a programação 17


Machine Translated by Google

Tutorial do Python, versão 3.11.3

18 Capítulo 3. Uma introdução informal ao Python


Machine Translated by Google

CAPÍTULO

QUATRO

MAIS FERRAMENTAS DE FLUXO DE CONTROLE

Além da instrução while que acabamos de apresentar, o Python usa as instruções de controle de fluxo conhecidas de outras linguagens, com
algumas alterações.

4.1 declarações if

Talvez o tipo de instrução mais conhecido seja a instrução if. Por exemplo:

>>> x = int(input("Por favor, digite um número inteiro: "))


Por favor, insira um número inteiro: 42
>>> se x < 0:
... x=0
... print('Negativo alterado para zero') ... elif x == 0:

... print('Zero') ... elif


x == 1:
... print('Single')
... mais:
... print('Mais')
...
Mais

Pode haver zero ou mais partes elif, e a parte else é opcional. A palavra-chave 'elif' é a abreviação de 'else if' e é útil para evitar recuo excessivo.
Uma sequência if … elif … elif … é um substituto para as instruções switch ou case encontradas em outras linguagens.

Se você estiver comparando o mesmo valor com várias constantes ou verificando tipos ou atributos específicos, também poderá achar útil a
instrução match. Para obter mais detalhes, consulte declarações de correspondência.

4.2 para Declarações

A instrução for em Python difere um pouco do que você pode estar acostumado em C ou Pascal. Em vez de sempre iterar sobre uma progressão
aritmética de números (como em Pascal), ou dar ao usuário a capacidade de definir tanto a etapa de iteração quanto a condição de parada (como
C), a instrução for do Python itera sobre os itens de qualquer sequência (uma lista ou uma string), na ordem em que aparecem na sequência. Por
exemplo (sem trocadilhos):

>>> # Meça algumas strings: ... words =


['cat', 'window', 'defenestrate'] >>> for w in words:

... print(w, len(w))


(continua na próxima página)

19
Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

...
gato 3
janela 6
defenestrar 12

O código que modifica uma coleção durante a iteração na mesma coleção pode ser difícil de acertar. Em vez disso, geralmente é mais
direto fazer um loop sobre uma cópia da coleção ou criar uma nova coleção:

# Crie uma coleção de amostras users =


{'Hans': 'active', 'Éléonore': 'inactive', '': 'active'}

# Strategy: Iterar sobre uma cópia para o usuário,


status in users.copy().items(): if status == 'inactive':

del users[usuário]

# Estratégia: Crie uma nova coleção active_users = {} para


o usuário, status em
users.items(): if status == 'active':

active_users[usuário] = status

4.3 A função range()

Se você precisar iterar em uma sequência de números, a função interna range() será útil. Gera progressões aritméticas:

>>> para i no intervalo(5):


... imprimir(i)
...
0
1
2
3
4

O ponto final fornecido nunca faz parte da sequência gerada; range(10) gera 10 valores, os índices legais para itens de uma seqüência
de comprimento 10. Épossível deixar o intervalo começar em outro número, ou especificar um incremento diferente (mesmo negativo;
às vezes isso é chamado de 'etapa' ):

>>> lista(range(5, 10)) [5, 6, 7, 8, 9]

>>> lista(intervalo(0, 10, 3)) [0, 3, 6, 9]

>>> lista(intervalo(-10, -100, -30)) [-10, -40, -70]

Para iterar sobre os índices de uma sequência, você pode combinar range() e len() da seguinte maneira:

>>> a = ['Mary', 'had', 'a', 'little', 'cordeiro'] >>> for i in range(len(a)):

(continua na próxima página)

20 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


... imprimir(i, a[i])
...
0 Maria
1 tinha
2a
3 pequenos
4 cordeiro

Na maioria desses casos, no entanto, é conveniente usar a função enumerate(), consulte Técnicas de Looping.

Uma coisa estranha acontece se você apenas imprimir um intervalo:

>>> intervalo(10)
intervalo(0, 10)

De muitas maneiras, o objeto retornado por range() se comporta como se fosse uma lista, mas na verdade não é. É um objeto que
retorna os itens sucessivos da sequência desejada quando você itera sobre ele, mas não faz parte da lista, economizando espaço.

Dizemos que tal objeto é iterável, ou seja, adequado como alvo para funções e construções que esperam algo do qual possam obter
itens sucessivos até que o suprimento se esgote. Vimos que a instrução for é uma dessas construções, enquanto um exemplo de
função que recebe um iterável é sum():

>>> soma(intervalo(4)) # 0 + 1 + 2 + 3 6

Mais tarde veremos mais funções que retornam iteráveis e recebem iteráveis como argumentos. No capítulo Estruturas de Dados,
discutiremos com mais detalhes sobre list().

4.4 Declarações break e continue, e cláusulas else em loops

A instrução break, como em C, sai do loop for ou while mais interno.

As instruções de loop podem ter uma cláusula else; ele é executado quando o loop termina por exaustão do iterável (com for) ou
quando a condição se torna falsa (com while), mas não quando o loop é encerrado por uma instrução break.
Isso é exemplificado pelo seguinte loop, que procura por números primos:

>>> para n no intervalo(2, 10): para x


... no intervalo(2, n): se n % x ==
... 0:
... print(n, 'igual', x, '*', n//x) quebrar
...
... outro:
... # loop falhou sem encontrar um fator print(n, 'é um número primo')
...
...
2 é um número primo 3 é um
número primo 4 é igual a 2 *
2 5 é um número
primo 6 é igual a 2 * 3 7 é um
número primo 8 é
igual a 2 * 4 9 é igual a 3 * 3

(Sim, este é o código correto. Observe atentamente: a cláusula else pertence ao loop for, não à instrução if.)

4.4. Declarações break e continue e cláusulas em loops 21


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Quando usada com um loop, a cláusula else tem mais em comum com a cláusula else de uma instrução try do que com as instruções if: a cláusula else
de uma instrução try é executada quando nenhuma exceção ocorre e a cláusula else de um loop é executada quando não há interrupção ocorre. Para
saber mais sobre a instrução try e as exceções, consulte Manipulando exceções.

A instrução continue, também emprestada de C, continua com a próxima iteração do loop:

>>> para num no intervalo (2, 10):


... se num % 2 == 0:
... print("Encontrou um número par", num)
... continuar
... print("Encontrou um número ímpar", num)
...
Encontrou um número par 2
Encontrou um número ímpar 3
Encontrou um número par 4
Encontrou um número ímpar 5
Encontrou um número par 6
Encontrou um número ímpar 7
Encontrou um número par 8
Encontrou um número ímpar 9

4.5 declarações de aprovação

A instrução pass não faz nada. Pode ser usado quando uma instrução é necessária sintaticamente, mas o programa não requer nenhuma ação. Por
exemplo:

>>> enquanto Verdadeiro:


... pass # Ocupado-espera pela interrupção do teclado (Ctrl+C)
...

Isso é comumente usado para criar classes mínimas:

>>> classe MyEmptyClass:


... passar
...

Outro local onde o passe pode ser usado é como um espaço reservado para uma função ou corpo condicional quando você está trabalhando em um
novo código, permitindo que você continue pensando em um nível mais abstrato. O passe é silenciosamente ignorado:

>>> def initlog(*args): pass #


... Lembre-se de implementar isso!
...

4.6 declarações de correspondência

Uma instrução de correspondência pega uma expressão e compara seu valor com padrões sucessivos fornecidos como um ou mais blocos de caso.
Isso é superficialmente semelhante a uma instrução switch em C, Java ou JavaScript (e em muitas outras linguagens), mas é mais semelhante à
correspondência de padrões em linguagens como Rust ou Haskell. Somente o primeiro padrão correspondente é executado e também pode extrair
componentes (elementos de sequência ou atributos de objeto) do valor em variáveis.

A forma mais simples compara um valor de assunto com um ou mais literais:

22 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

Tutorial do Python, versão 3.11.3

def http_error(status): corresponde


ao status:
caso 400:
return "Pedido inválido" caso
404:
return "Não encontrado"
caso 418:
return "Eu sou um bule de chá"
caso _:
return "Algo está errado com a internet"

Observe o último bloco: as ramificações “nome da _ atua como um curinga e nunca deixa de corresponder. Se nenhum caso corresponder, nenhum dos
variável” são executadas.

Você pode combinar vários literais em um único padrão usando | ("ou"):

caso 401 | 403 | 404:


return "Não permitido"

Os padrões podem parecer atribuições de desempacotamento e podem ser usados para vincular variáveis:

# ponto é um ponto de correspondência


de tupla (x, y) :
case (0, 0):
print("Origin") case (0,
y): print(f"Y={y}")
case (x, 0): print(f"X={x}")
case (x, y):
print(f"X={x}, Y={y}")

caso _:
raise ValueError("Não é um ponto")

Estude esse cuidadosamente! O primeiro padrão tem dois literais e pode ser pensado como uma extensão do padrão literal mostrado acima. Mas os próximos
dois padrões combinam um literal e uma variável, e a variável vincula um valor do sujeito (ponto). O quarto padrão captura dois valores, o que o torna
conceitualmente semelhante à atribuição de desempacotamento (x, y) = ponto.

Se você estiver usando classes para estruturar seus dados, poderá usar o nome da classe seguido por uma lista de argumentos semelhante a um construtor,
mas com a capacidade de capturar atributos em variáveis:

ponto de classe :
x: inteiro
y: int

def where_is(point): match point:


case Point(x=0,
y=0): print("Origin") case Point(x=0,
y=y): print(f"Y={y}") case
Point(x=x, y=0): print(f"X={x}")

case Point():
print("Em outro lugar")
caso _:
print("Não é um ponto")

4.6. declarações de correspondência 23


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Você pode usar parâmetros posicionais com algumas classes internas que fornecem uma ordem para seus atributos (por exemplo, dataclasses).
Você também pode definir uma posição específica para atributos em padrões configurando o atributo especial __match_args__ em suas classes. Se
for definido como (“x”, “y”), os seguintes padrões são todos equivalentes (e todos ligam o atributo y à variável var):

Ponto(1, var)
Ponto(1, y=var)
Ponto(x=1, y=var)
Ponto(y=var, x=1)

Uma maneira recomendada de ler padrões é vê-los como uma forma estendida do que você colocaria à esquerda de uma atribuição, para entender
quais variáveis seriam definidas para quê. Somente os nomes autônomos (como var acima) são atribuídos por uma instrução de correspondência.
Nomes pontilhados (como foo.bar), nomes de atributo (o x= e y= acima) ou nomes de classe (reconhecidos pelo “(…)” ao lado deles como Ponto
acima) nunca são atribuídos.

Os padrões podem ser aninhados arbitrariamente. Por exemplo, se tivermos uma pequena lista de pontos, podemos combiná-la assim:

pontos de

correspondência : case []:


print("Sem pontos") case
[Ponto(0, 0)]: print("A origem")
case [Ponto(x, y)]: print(f"Ponto
único {x} , {y}")
caso [Ponto(0, y1), Ponto(0, y2)]:
print(f"Dois no eixo Y em {y1}, {y2}")
caso _:
print("Algo mais")

Podemos adicionar uma cláusula if a um padrão, conhecida como “guarda”. Se a guarda for falsa, a correspondência prossegue para tentar o próximo bloco de caso.
Observe que a captura de valor ocorre antes que a guarda seja avaliada:

ponto de partida :
case Point(x, y) if x == y: print(f"Y=X em
{x}") case Point(x, y): print(f"Não
está na diagonal")

Vários outros recursos importantes desta declaração:

• Assim como as atribuições de descompactação, os padrões de tupla e lista têm exatamente o mesmo significado e, na verdade, correspondem de forma arbitrária
sequências. Uma exceção importante é que eles não correspondem a iteradores ou strings.

• Padrões de sequência suportam descompactação estendida: [x, y, *rest] e (x, y, *rest) funcionam de maneira semelhante a un, então (x, y, *_)
tarefas de embalagem. O nome após * também pode não vincular_, corresponde a uma sequência de pelo menos dois itens
os itens restantes.

• Padrões de mapeamento: {"bandwidth": b, "latency": l} captura os valores de "bandwidth" e "latency" de um dicionário. Ao contrário dos padrões
de sequência, as chaves extras são ignoradas. Uma descompactação como **rest também é suportada. (Mas **_ seria redundante, então não
é permitido.)

• Os subpadrões podem ser capturados usando a palavra-chave as:

caso (Ponto(x1, y1), Ponto(x2, y2) como p2): ...

irá capturar o segundo elemento da entrada como p2 (desde que a entrada seja uma sequência de dois pontos)

• A maioria dos literais é comparada por igualdade, porém os singletons True, False e None são comparados por identidade.

24 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

Tutorial do Python, versão 3.11.3

• Os padrões podem usar constantes nomeadas. Estes devem ser nomes pontilhados para evitar que sejam interpretados como captura
variável:

from enum import Classe Enum


Color(Enum):
VERMELHO = 'vermelho'

VERDE = 'verde'
AZUL = 'azul'

color = Color(input("Digite sua escolha de 'vermelho', 'azul' ou 'verde': "))

combinar cor:
cor da caixa.VERMELHO:
print("Eu vejo vermelho!")
case Color.GREEN:
print("A grama é verde") case
Color.BLUE:
print("Estou me sentindo triste :(")

Para uma explicação mais detalhada e exemplos adicionais, você pode consultar o PEP 636 que é escrito em um formato de tutorial.

4.7 Definindo funções

Podemos criar uma função que escreve a série de Fibonacci em um limite arbitrário:

>>> def fib(n): # escreve a série de Fibonacci até n """Imprime uma


... série de Fibonacci até n.""" a, b = 0, 1 while a < n:
...
...
... print(a, end=' ') a, b = b, a+b
...
... imprimir()
...
>>> # Agora chame a função que acabamos de definir: ... fib(2000)

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

A palavra-chave def apresenta uma definição de função. Deve ser seguido pelo nome da função e a lista entre parênteses de parâmetros
formais. As instruções que formam o corpo da função começam na próxima linha e devem ser indentadas.

A primeira instrução do corpo da função pode opcionalmente ser uma string literal; essa string literal é a string de documentação da função,
ou docstring. (Mais informações sobre docstrings podem ser encontradas na seção Documentation Strings.) Existem ferramentas que usam
docstrings para produzir automaticamente documentação on-line ou impressa, ou para permitir que o usuário navegue interativamente pelo
código; é uma boa prática incluir docstrings no código que você escreve, então faça disso um hábito.

A execução de uma função introduz uma nova tabela de símbolos usada para as variáveis locais da função. Mais precisamente, todas as
atribuições de variáveis em uma função armazenam o valor na tabela de símbolos local; enquanto as referências de variáveis primeiro
procuram na tabela de símbolos locais, depois nas tabelas de símbolos locais de funções envolventes, depois na tabela de símbolos globais
e, finalmente, na tabela de nomes integrados. Assim, variáveis globais e variáveis de funções delimitadoras não podem ser diretamente
atribuídas a um valor dentro de uma função (a menos que, para variáveis globais, nomeadas em uma instrução global ou, para variáveis de
funções delimitadoras, nomeadas em uma instrução não local), embora possam ser referenciado.

Os parâmetros reais (argumentos) para uma chamada de função são introduzidos na tabela de símbolos local da função chamada quando
ela é chamada; assim, os argumentos são passados usando chamada por valor (onde o valor é sempre uma referência de objeto, não o valor de

4.7. Definindo funções 25


Machine Translated by Google

Tutorial do Python, versão 3.11.3

o objeto).1 Quando uma função chama outra função, ou chama a si mesma recursivamente, uma nova tabela de símbolos local é criada para aquela
chamar.

Uma definição de função associa o nome da função ao objeto de função na tabela de símbolos atual. O interpretador reconhece o objeto apontado
por esse nome como uma função definida pelo usuário. Outros nomes também podem apontar para o mesmo objeto de função e também podem
ser usados para acessar a função:

>>> mentira
<função fib em 10042ed0>
>>> f = fib
>>> f(100) 0 1
1 2 3 5 8 13 21 34 55 89

Vindo de outras linguagens, você pode objetar que fib não é uma função, mas um procedimento, pois não retorna um valor.
Na verdade, mesmo as funções sem uma instrução de retorno retornam um valor, embora um valor bastante chato. Esse valor é chamado None (é
um nome interno). Escrever o valor None é normalmente suprimido pelo interpretador se for o único valor escrito. Você pode ver se realmente quiser
usar print():

>>> fib(0) >>>


print(fib(0))
Nenhum

É simples escrever uma função que retorne uma lista dos números da série de Fibonacci, ao invés de imprimi-la:

>>> def fib2(n): # retorna a série Fibonacci até n """Retorna uma lista contendo a série
... Fibonacci até n.""" resultado = [] a, b = 0, 1 while a < n:
...
...
...
... result.append(a) a, b = b, # Veja abaixo
... a+b
... resultado de retorno
...
>>> f100 = fib2(100) >>> f100 # chame-o
# escreve o resultado
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

Este exemplo, como sempre, demonstra alguns novos recursos do Python:

• A instrução return retorna com um valor de uma função. return sem um argumento de expressão retorna
Nenhum. Cair no final de uma função também retorna None.

• A instrução result.append(a) chama um método do objeto lista result. Um método é uma função que 'pertence' a um objeto e é denominada
obj.methodname, onde obj é algum objeto (pode ser uma expressão) e methodname é o nome de um método definido pelo tipo do objeto.
Tipos diferentes definem métodos diferentes. Métodos de tipos diferentes podem ter o mesmo nome sem causar ambiguidade. (É possível
definir seus próprios tipos de objeto e métodos, usando classes, veja Classes) O método append() mostrado no exemplo é definido para
objetos de lista; adiciona um novo elemento no final da lista. Neste exemplo, é equivalente a result = result + [a], mas mais eficiente.

1 Na verdade, chamar por referência de objeto seria uma descrição melhor, pois se um objeto mutável for passado, o chamador verá todas as alterações feitas pelo chamado
a ele (itens inseridos em uma lista).

26 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

Tutorial do Python, versão 3.11.3

4.8 Mais sobre como definir funções

Também é possível definir funções com um número variável de argumentos. Existem três formas, que podem ser combinadas.

4.8.1 Valores de argumento padrão

A forma mais útil é especificar um valor padrão para um ou mais argumentos. Isso cria uma função que pode ser chamada com menos
argumentos do que foi definido para permitir. Por exemplo:

def ask_ok(prompt, retries=4, lembrete='Por favor, tente novamente!'): while True:

ok = input(prompt) if ok in ('y',
'ye', 'yes'): return True

if ok in ('n', 'no', 'nop', 'nope'):


retorna falso
tentativas = novas tentativas - 1
se novas tentativas < 0:
raise ValueError(' resposta inválida do usuário') print(lembrete)

Esta função pode ser chamada de várias maneiras:

• dando apenas o argumento obrigatório: ask_ok('Você realmente quer sair?')

• fornecendo um dos argumentos opcionais: ask_ok('OK to overwrite the file?', 2)

• ou mesmo dando todos os argumentos: ask_ok('OK to overwrite the file?', 2, 'Vamos lá, só
sim ou não!')

Este exemplo também apresenta a palavra-chave in. Isso testa se uma sequência contém ou não um determinado valor.

Os valores padrão são avaliados no ponto de definição da função no escopo de definição , de modo que

eu = 5

def f(arg=i): print(arg)

eu = 6
f()

imprimirá 5.

Aviso importante: O valor padrão é avaliado apenas uma vez. Isso faz diferença quando o padrão é um objeto mutável como uma
lista, dicionário ou instâncias da maioria das classes. Por exemplo, a função a seguir acumula os argumentos passados para ela em
chamadas subsequentes:

def f(a, L=[]):


L.acrescentar(a)
retornar L

imprimir(f(1))
imprimir(f(2))
imprimir(f(3))

isso vai imprimir

4.8. Mais sobre como definir funções 27


Machine Translated by Google

Tutorial do Python, versão 3.11.3

[1]
[1, 2] [1,
2, 3]

Se você não deseja que o padrão seja compartilhado entre as chamadas subsequentes, pode escrever a função assim:

def f(a, L=Nenhum): se L


for Nenhum:
L = []
L.apêndice(a)
retorna L

4.8.2 Argumentos de palavras-chave

As funções também podem ser chamadas usando argumentos de palavras-chave na forma kwarg=valor. Por exemplo, a seguinte função:

def parrot(tensão, estado='um rígido', ação='voom', tipo='Norwegian Blue'):


print("-- Este papagaio não iria", ação, end=' ') print("se você colocar", voltagem, "volts
através dele.") print("-- Linda plumagem, a", digite) print( ("-- É", estado, "!")

aceita um argumento obrigatório (tensão) e três argumentos opcionais (estado, ação e tipo). Esta função pode ser chamada de qualquer uma
das seguintes maneiras:

parrot(1000) # 1 argumento posicional # 1 argumento de palavra-chave parrot(voltage=1000) # 2 argumentos de palavra-chave


action='VOOOOOM') # 2 argumentos parrot(voltage=1000000,
milhão', 'desprovido de vida', 'pular') parrot('
de palavra-chave
mil', estado='empurrando
parrot(action='VOOOOOM',
as voltage=1000000) # 3 argumentos posicionais parrot('um
margaridas') # 1 posicional, 1 palavra-chave

mas todas as chamadas a seguir seriam inválidas:

# argumento obrigatório faltando parrot()


parrot(voltage=5.0, 'dead') # argumento sem palavra-chave após um argumento com palavra-chave # valor duplicado para o mesmo argumento
palavra-chave desconhecida parrot(110, voltage=220) parrot(actor='John Cleese') # argumento de

Em uma chamada de função, os argumentos de palavra-chave devem seguir os argumentos posicionais. Todos os argumentos de palavra-
chave passados devem corresponder a um dos argumentos aceitos pela função (por exemplo, ator não é um argumento válido para a função
papagaio) e sua ordem não é importante. Isso também inclui argumentos não opcionais (por exemplo, parrot(tensão=1000) também é válido).
Nenhum argumento pode receber um valor mais de uma vez. Aqui está um exemplo que falha devido a essa restrição:

>>> função def (a):


... passar
...
>>> função(0, a=0)
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
TypeError: function () obteve vários valores para o argumento 'a'

Quando um parâmetro formal final da forma **name está presente, ele recebe um dicionário (consulte mapeamento de tipos) contendo todos
os argumentos de palavras-chave, exceto aqueles correspondentes a um parâmetro formal. Isso pode ser combinado com um parâmetro
formal da forma *name (descrito na próxima subseção) que recebe uma tupla contendo os argumentos posicionais além da lista de parâmetros
formais. (*nome deve ocorrer antes de **nome.) Por exemplo, se definirmos uma função como esta:

28 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

Tutorial do Python, versão 3.11.3

def cheeseshop(tipo, *argumentos, **palavras-chave): print("-- Você tem


algum", tipo, "?") print("-- Desculpe, estamos sem", tipo) para arg
em argumentos:

print(arg) print("-"
* 40) para kw em
palavras-chave: print(kw, ":",
palavras-chave[kw])

Poderia ser chamado assim:

cheeseshop("Limburger", "Está muito escorrendo, senhor.", "Está realmente muito,


MUITO escorrendo, senhor.", shopkeeper="Michael Palin",
client="John Cleese", sketch="Cheese Shop
Sketch")

e é claro que imprimiria:

-- Vocÿ tem Limburger ?


-- Sinto muito, estamos todos sem Limburger. Está muito escorrendo,
senhor.
Está realmente muito, MUITO escorrendo, senhor.
----------------------------------------

lojista : Michael Palin cliente : John Cleese

esboço: esboço da loja de queijos

Observe que a ordem na qual os argumentos de palavra-chave são impressos é garantida para corresponder à ordem em que foram fornecidos na
chamada de função.

4.8.3 Parâmetros especiais

Por padrão, os argumentos podem ser passados para uma função Python por posição ou explicitamente por palavra-chave. Para facilitar a leitura e
o desempenho, faz sentido restringir a maneira como os argumentos podem ser passados para que um desenvolvedor precise apenas examinar a
definição da função para determinar se os itens são passados por posição, por posição ou palavra-chave ou por palavra-chave.

Uma definição de função pode se parecer com:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):


----------- ---------- ----------

| ||

|
Posicional ou palavra-chave |
|
- Somente palavras-chave
-- Somente posicional

onde / e * são opcionais. Se usados, esses símbolos indicam o tipo de parâmetro pelo qual os argumentos podem ser passados para a função:
somente posicional, posicional ou palavra-chave e somente palavra-chave. Parâmetros de palavras-chave também são chamados de parâmetros
nomeados.

4.8. Mais sobre como definir funções 29


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Argumentos posicionais ou de palavra-chave

Se / e * não estiverem presentes na definição da função, os argumentos podem ser passados para uma função por posição ou por palavra-chave.

Parâmetros somente posicionais

Olhando para isso com um pouco mais de detalhes, é possível marcar certos parâmetros como somente posicionais. Se for somente posicional, a
ordem dos parâmetros é importante e os parâmetros não podem ser passados por palavra-chave. Parâmetros somente posicionais são colocados
antes de uma / (barra). O / é usado para separar logicamente os parâmetros somente posicionais do restante dos parâmetros. Se não houver / na
definição da função, não haverá parâmetros somente posicionais.

Os parâmetros após o / podem ser posicionais ou palavras-chave ou apenas palavras-chave.

Argumentos somente de palavra-chave

Para marcar parâmetros como somente palavra-chave, indicando que os parâmetros devem ser passados por argumento de palavra-chave, coloque um * na lista
de argumentos logo antes do primeiro parâmetro somente de palavra-chave .

Exemplos de funções

Considere as seguintes definições de função de exemplo prestando muita atenção aos marcadores / e *:

>>> def standard_arg(arg): print(arg)


...
...
>>> def pos_only_arg(arg, /):
... imprimir(arg)
...
>>> def kwd_only_arg(*, arg): print(arg)
...
...
>>> def combined_example(pos_only, /, standard, *, kwd_only):
... print(pos_only, padrão, kwd_only)

A primeira definição de função, standard_arg, a forma mais familiar, não impõe restrições à convenção de chamada e os argumentos podem ser
passados por posição ou palavra-chave:

>>> standard_arg(2) 2

>>> standard_arg(arg=2) 2

A segunda função pos_only_arg é restrita para usar apenas parâmetros posicionais, pois há um / na definição da função:

>>> pos_only_arg(1) 1

>>> pos_only_arg(arg=1)
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
TypeError: pos_only_arg() recebeu alguns argumentos somente posicionais passados como palavra-chaveÿ
ÿargumentos: 'arg'

30 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

Tutorial do Python, versão 3.11.3

A terceira função kwd_only_args permite apenas argumentos de palavras-chave conforme indicado por um * na definição da função:

>>> kwd_only_arg(3)
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
TypeError: kwd_only_arg () aceita 0 argumentos posicionais, mas 1 foi fornecido

>>> kwd_only_arg(arg=3) 3

E o último usa todas as três convenções de chamada na mesma definição de função:

>>> exemplo_combinado(1, 2, 3)
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
TypeError: combinado_exemplo () leva 2 argumentos posicionais, mas 3 foram fornecidos

>>> exemplo_combinado(1, 2, kwd_only=3) 1 2 3

>>> exemplo_combinado(1, padrão=2, kwd_only=3) 1 2 3

>>> exemplo_combinado(pos_only=1, padrão=2, kwd_only=3)


Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
TypeError: Combined_example() obteve alguns argumentos somente posicionais passados como palavra-chaveÿ
ÿargumentos: 'pos_only'

Finalmente, considere esta definição de função que tem uma colisão potencial entre o nome do argumento posicional e **kwds que tem
nome como uma chave:

def foo(nome, **kwds):


retornar 'nome' em kwds

Não há chamada possível que o faça retornar True, pois a palavra-chave 'name' sempre será vinculada ao primeiro parâmetro.
Por exemplo:

>>> foo(1, **{'nome': 2})


Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
TypeError: foo () obteve vários valores para o argumento 'name'
>>>

Mas usar / (somente argumentos posicionais), é possível, pois permite nome como um argumento posicional e 'nome' como uma chave nos
argumentos de palavra-chave:

>>> def foo(nome, /, **kwds): return 'nome' em


... kwds
...
>>> foo(1, **{'nome': 2})
Verdadeiro

Em outras palavras, os nomes dos parâmetros somente posicionais podem ser usados em **kwds sem ambigüidade.

4.8. Mais sobre como definir funções 31


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Recapitular

O caso de uso determinará quais parâmetros usar na definição da função:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

Como orientação:

• Use apenas posicional se desejar que o nome dos parâmetros não esteja disponível para o usuário. Isso é útil quando os nomes dos
parâmetros não têm significado real, se você deseja impor a ordem dos argumentos quando a função é chamada ou se precisa obter
alguns parâmetros posicionais e palavras-chave arbitrárias.

• Use apenas palavras-chave quando os nomes tiverem significado e a definição da função for mais compreensível por ser explícita
com nomes ou você deseja impedir que os usuários confiem na posição do argumento que está sendo passado.

• Para uma API, use apenas posicional para evitar mudanças de API se o nome do parâmetro for modificado no futuro.

4.8.4 Listas de Argumentos Arbitrários

Finalmente, a opção menos usada é especificar que uma função pode ser chamada com um número arbitrário de argumentos.
Esses argumentos serão agrupados em uma tupla (consulte Tuplas e Sequências). Antes do número variável de argumentos, podem ocorrer
zero ou mais argumentos normais.

def write_multiple_items(arquivo, separador, *args): file.write(separator.join(args))

Normalmente, esses argumentos variáveis serão os últimos na lista de parâmetros formais, porque eles coletam todos os argumentos de
entrada restantes que são passados para a função. Quaisquer parâmetros formais que ocorram após o parâmetro *args são argumentos
'somente palavras-chave', o que significa que eles só podem ser usados como palavras-chave em vez de argumentos posicionais.

>>> def concat(*args, sep="/"): return


... sep.join(args)
...
>>> concat("terra", "marte", "venus") 'terra/marte/venus'
>>> concat("terra", "marte",
"venus", sep=".") 'terra. marte.venus'

4.8.5 Descompactando listas de argumentos

A situação inversa ocorre quando os argumentos já estão em uma lista ou tupla, mas precisam ser descompactados para uma chamada de
função que requer argumentos posicionais separados. Por exemplo, a função interna range() espera argumentos de início e parada separados.
Se eles não estiverem disponíveis separadamente, escreva a chamada de função com o operador * para desempacotar os argumentos de uma
lista ou tupla:

>>> lista(intervalo(3, 6)) [3, 4, 5] # chamada normal com argumentos separados


>>> args =
[3, 6] >>>
lista(intervalo(*args)) [3, 4, 5] # chamada com argumentos descompactados de uma lista

Da mesma forma, os dicionários podem fornecer argumentos de palavra-chave com o operador **:

32 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> def parrot(voltage, state='a rigid', action='voom'):


... print("-- Este papagaio não faria", ação, end=' ') print("se você colocar",
... tensão, "volts através dele.", end=' ') print("E's", estado, " !")
...
...
>>> d = {"tensão": "quatro milhões", "estado": "morte sangrando", "ação": "VOOM"} >>> papagaio(**d)

-- Este papagaio não faria VOOM se você colocasse quatro milhões de volts nele. E está sangrandoÿ
ÿdemitido!

4.8.6 Expressões Lambda

Pequenas funções anônimas podem ser criadas com a palavra-chave lambda. Esta função retorna a soma de seus dois argumentos: lambda a, b: a+b.
As funções do Lambda podem ser usadas sempre que os objetos de função forem necessários. Eles são sintaticamente restritos a uma única expressão.
Semanticamente, eles são apenas açúcar sintático para uma definição de função normal. Assim como as definições de funções aninhadas, as funções
lambda podem fazer referência a variáveis do escopo recipiente:

>>> def make_incrementor(n): return lambda


... x: x + n
...
>>> f = make_incrementor(42) >>> f(0) 42

>>> f(1) 43

O exemplo acima usa uma expressão lambda para retornar uma função. Outro uso é passar uma pequena função como argumento:

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] >>> pairs.sort(key=lambda pair: par[1]) >>>
pares [(4, 'quatro'), (1, 'um'), (3, 'três'), (2, 'dois')]

4.8.7 Cadeias de Documentação

Aqui estão algumas convenções sobre o conteúdo e formatação de strings de documentação.

A primeira linha deve ser sempre um resumo curto e conciso da finalidade do objeto. Por brevidade, ele não deve declarar explicitamente o nome ou o
tipo do objeto, pois eles estão disponíveis por outros meios (exceto se o nome for um verbo descrevendo a operação de uma função). Esta linha deve
começar com uma letra maiúscula e terminar com um ponto.

Se houver mais linhas na string de documentação, a segunda linha deve ficar em branco, separando visualmente o resumo do restante da descrição. As
linhas a seguir devem ser um ou mais parágrafos descrevendo as convenções de chamada do objeto, seus efeitos colaterais, etc.

O analisador do Python não remove a indentação de literais de string de várias linhas em Python, portanto, as ferramentas que processam a
documentação precisam remover a indentação, se desejado. Isso é feito usando a seguinte convenção. A primeira linha não em branco após a primeira
linha da string determina a quantidade de recuo para toda a string de documentação. (Não podemos usar a primeira linha, pois geralmente é adjacente
às aspas de abertura da string, portanto, seu recuo não é aparente na string literal.) O espaço em branco “equivalente” a esse recuo é removido do início
de todas as linhas da string . Linhas com menos recuo não devem ocorrer, mas se ocorrerem, todos os espaços em branco à esquerda devem ser
removidos. A equivalência de espaços em branco deve ser testada após a expansão das tabulações (para 8 espaços, normalmente).

Aqui está um exemplo de uma docstring de várias linhas:

4.8. Mais sobre como definir funções 33


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> def my_function(): """Não


... faça nada, apenas documente.
...
... Não, realmente, não faz nada.
... """
... passar
...
>>> print(minha_função.__doc__)
Não faça nada, apenas documente.

Não, realmente, não faz nada.

4.8.8 Anotações de função

As anotações de função são informações de metadados completamente opcionais sobre os tipos usados por funções definidas pelo usuário
(consulte PEP 3107 e PEP 484 Para maiores informações).

As anotações são armazenadas no atributo __annotations__ da função como um dicionário e não têm efeito em nenhuma outra parte da função.
As anotações de parâmetro são definidas por dois pontos após o nome do parâmetro, seguido por uma expressão avaliada para o valor da
anotação. As anotações de retorno são definidas por um literal ->, seguido por uma expressão, entre a lista de parâmetros e os dois pontos
indicando o final da instrução def. O exemplo a seguir tem um argumento obrigatório, um argumento opcional e o valor de retorno anotado:

>>> def f(presunto: str, eggs: str = 'ovos') -> str:


... print("Anotações:", f.__annotations__) print("Argumentos:",
... presunto, ovos) return presunto + ' e '
... + ovos
...
>>> f('spam')
Anotações: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Argumentos: ovos de spam
'spam e ovos'

4.9 Intermezzo: Estilo de Codificação

Agora que você está prestes a escrever partes mais longas e complexas de Python, é um bom momento para falar sobre estilo de codificação. A
maioria das linguagens pode ser escrita (ou mais concisa, formatada) em diferentes estilos; alguns são mais legíveis do que outros. Tornar mais
fácil para os outros lerem seu código é sempre uma boa ideia, e adotar um bom estilo de codificação ajuda tremendamente nisso.

Para Python, PEP 8 surgiu como o guia de estilo ao qual a maioria dos projetos adere; promove um estilo de codificação muito legível e agradável
aos olhos. Todo desenvolvedor Python deve lê-lo em algum momento; aqui estão os pontos mais importantes extraídos para você:

• Use recuo de 4 espaços e sem tabulações.

4 espaços são um bom compromisso entre recuo pequeno (permite maior profundidade de aninhamento) e recuo grande (mais fácil de
ler). As guias introduzem confusão e é melhor deixá-las de fora.

• Quebre as linhas para que não excedam 79 caracteres.

Isso ajuda os usuários com telas pequenas e torna possível ter vários arquivos de código lado a lado em telas maiores.

• Use linhas em branco para separar funções e classes e blocos maiores de código dentro das funções.

• Sempre que possível, coloque comentários em uma linha própria.

34 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

Tutorial do Python, versão 3.11.3

• Use docstrings.

• Use espaços ao redor de operadores e após vírgulas, mas não diretamente dentro de construções de colchetes: a = f(1, 2) +
g(3, 4).

• Nomeie suas classes e funções de forma consistente; a convenção é usar UpperCamelCase para classes e
lowercase_with_underscores para funções e métodos. Sempre use self como o nome para o primeiro argumento do método
(consulte Uma primeira olhada nas classes para saber mais sobre classes e métodos).

• Não use codificações sofisticadas se seu código for usado em ambientes internacionais. padrão do Python, UTF-8,
ou mesmo ASCII simples funcionam melhor em qualquer caso.

• Da mesma forma, não use caracteres não ASCII em identificadores se houver a menor chance de as pessoas falarem um
idioma diferente irá ler ou manter o código.

4.9. Intermezzo: estilo de codificação 35


Machine Translated by Google

Tutorial do Python, versão 3.11.3

36 Capítulo 4. Mais ferramentas de fluxo de controle


Machine Translated by Google

CAPÍTULO

CINCO

ESTRUTURAS DE DADOS

Este capítulo descreve algumas coisas sobre as quais você já aprendeu com mais detalhes e também adiciona algumas coisas novas.

5.1 Mais sobre listas

O tipo de dados de lista tem mais alguns métodos. Aqui estão todos os métodos de objetos de lista:

list.append(x)
Adicione um item ao final da lista. Equivalente a a[len(a):] = [x].

list.extend(iterável)
Estenda a lista anexando todos os itens do iterável. Equivalente a a[len(a):] = iterável.

lista.insert(i, x)
Insira um item em uma determinada posição. O primeiro argumento é o índice do elemento antes do qual inserir, então a.
insert(0, x) insere na frente da lista e a.insert(len(a), x) é equivalente a a.append(x).

lista.remove(x)
Remova o primeiro item da lista cujo valor é igual a x. Ele gera um ValueError se não houver tal item.

lista.pop([i])
Remova o item na posição especificada na lista e devolva-o. Se nenhum índice for especificado, a.pop() remove e retorna o
último item da lista. (Os colchetes ao redor do i na assinatura do método indicam que o parâmetro é opcional, não que você
deva digitar colchetes nessa posição. Você verá essa notação com frequência na Referência da Biblioteca Python.)

lista.limpar()
Remova todos os itens da lista. Equivalente a del a[:].

lista.index(x[, início[, fim ] ])


Retorna o índice baseado em zero na lista do primeiro item cujo valor é igual a x. Gera um ValueError se não houver tal item.

Os argumentos opcionais start e end são interpretados como na notação da fatia e são usados para limitar a pesquisa a uma
subsequência específica da lista. O índice retornado é calculado em relação ao início da sequência completa, em vez do
argumento inicial .

lista.contagem(x)
Retorna o número de vezes que x aparece na lista.

list.sort(*, key=None, reverse=False)


Classifique os itens da lista no local (os argumentos podem ser usados para personalização de classificação, consulte sorted() para
obter a explicação).

37
Machine Translated by Google

Tutorial do Python, versão 3.11.3

list.reverse()

Inverta os elementos da lista no lugar.

list.copy()
Retorne uma cópia rasa da lista. Equivalente a um [:].

Um exemplo que usa a maioria dos métodos de lista:

>>> frutas = ['laranja', 'maçã', 'pêra', 'banana', 'kiwi', 'maçã', 'banana'] >>> frutas.count('maçã') 2

>>> frutas.contagem('tangerina') 0

>>> frutas.index('banana') 3

>>> fruits.index('banana', 4) # Encontre a próxima banana começando na posição 4 6

>>> frutas.reverse() >>> frutas

['banana', 'maçã', 'kiwi', 'banana', 'pêra', 'maçã', 'laranja'] >>> frutas.append ('uva') >>> frutas

['banana', 'maçã', 'kiwi', 'banana', 'pêra', 'maçã', 'laranja', 'uva'] >>> frutas.sort ( ) >>> frutas

['maçã', 'maçã', 'banana', 'banana', 'uva', 'kiwi', 'laranja', 'pêra'] >>> frutas.pop() ' pêra '

Você deve ter notado que métodos como insert, remove ou sort, que apenas modificam a lista, não têm valor de retorno impresso –
1
eles retornam o padrão None. Este é um princípio de design para todas as estruturas de dados mutáveis em Python.

Outra coisa que você pode notar é que nem todos os dados podem ser classificados ou comparados. Por exemplo, [None, 'hello', 10]
não classifica porque inteiros não podem ser comparados a strings e None não pode ser comparado a outros tipos. Além disso, existem
alguns tipos que não possuem uma relação de ordenação definida. Por exemplo, 3+4j < 5+7j não é uma comparação válida.

5.1.1 Usando listas como pilhas

Os métodos de lista tornam muito fácil usar uma lista como uma pilha, onde o último elemento adicionado é o primeiro elemento
recuperado (“último a entrar, primeiro a sair”). Para adicionar um item ao topo da pilha, use append(). Para recuperar um item do topo
da pilha, use pop() sem um índice explícito. Por exemplo:

>>> pilha = [3, 4, 5] >>> pilha.append(6)


>>> pilha.append(7) >>> pilha

[3, 4, 5, 6, 7] >>> stack.pop()


7

>>> pilha
[3, 4, 5, 6] >>>
stack.pop() 6

>>> stack.pop() 5

(continua na próxima página)

1 Outras linguagens podem retornar o objeto modificado, que permite o encadeamento de métodos, como d->insert("a")->remove("b")->sort();.

38 Capítulo 5. Estruturas de Dados


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


>>> pilha
[3, 4]

5.1.2 Usando listas como filas

Também é possível usar uma lista como uma fila, onde o primeiro elemento adicionado é o primeiro elemento recuperado (“first-in, first-out”); no
entanto, as listas não são eficientes para essa finalidade. Enquanto appends e pops do final da lista são rápidos, fazer inserções ou pops do
início de uma lista é lento (porque todos os outros elementos precisam ser deslocados em um).

Para implementar uma fila, use collections.deque, que foi projetado para ter anexos e pops rápidos de ambas as extremidades.
Por exemplo:

>>> from collections import deque >>> queue =


deque(["Eric", "John", "Michael"]) >>> queue.append("Terry") >>>
queue.append("Graham") >>> fila.popleft() #terry chega
#Graham chega
# O primeiro a chegar agora sai
'Eric'
>>> fila.popleft() # O segundo a chegar agora sai
'John'
'Terry', 'Graham']) # Fila restante por ordem de chegada >>> fila deque(['Michael',

5.1.3 Abrangências de Lista

As compreensões de lista fornecem uma maneira concisa de criar listas. Aplicações comuns são para fazer novas listas onde cada elemento é o
resultado de algumas operações aplicadas a cada membro de outra sequência ou iterável, ou para criar uma subsequência daqueles elementos
que satisfazem uma determinada condição.

Por exemplo, suponha que queremos criar uma lista de quadrados, como:

>>> squares = [] >>> para


x in range(10): squares.append(x**2)
...
...
>>> quadrados [0,
1, 4, 9, 16, 25, 36, 49, 64, 81]

Observe que isso cria (ou sobrescreve) uma variável chamada x que ainda existe após a conclusão do loop. Podemos calcular a lista de
quadrados sem nenhum efeito colateral usando:

squares = list(map(lambda x: x**2, range(10)))

ou equivalente:

quadrados = [x**2 para x no intervalo(10)]

que é mais conciso e legível.

Uma compreensão de lista consiste em colchetes contendo uma expressão seguida por uma cláusula for e, em seguida, zero ou mais cláusulas
for ou if. O resultado será uma nova lista resultante da avaliação da expressão no contexto das cláusulas for e if que a seguem. Por exemplo,
este listcomp combina os elementos de duas listas se não forem iguais:

5.1. Mais sobre listas 39


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> [(x, y) para x em [1,2,3] para y em [3,1,4] se x != y] [(1, 3), (1, 4), (2 , 3), (2, 1), (2, 4),
(3, 1), (3, 4)]

e é equivalente a:

>>> combs = [] >>>


for x in [1,2,3]: for y in [3,1,4]: if
... x != y: combs.append((x, y))
...
...
...
>>> pentes
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Observe como a ordem das instruções for e if é a mesma em ambos os trechos.

Se a expressão for uma tupla (por exemplo, o (x, y) no exemplo anterior), ela deve ser colocada entre parênteses.

>>> vec = [-4, -2, 0, 2, 4] >>> # cria uma


nova lista com os valores dobrados
>>> [x*2 para x em vec]
[-8, -4, 0, 4, 8] >>> # filtra
a lista para excluir números negativos >>> [x for x in vec if x >= 0]

[0, 2, 4] >>>
# aplica uma função a todos os elementos >>> [abs(x) for x in vec]
[4, 2, 0, 2, 4] >>> # chama um método
cada elemento >>>
fruta fresca = ['banana', 'loganberry ', 'maracujá '] >>>
[weapon.strip() para arma em fruta fresca] ['banana', 'loganberry', 'maracujá'] > >> # cria uma lista de 2-
tuplas como (number, square) >>> [(x, x**2) for x in range(6)] [(0, 0), (1,
1), ( 2, 4), (3, 9), (4, 16), (5, 25)] >>> # a tupla deve estar entre
parênteses, caso contrário, um erro é gerado >>> [x, x**2 for x no intervalo (6)]

Arquivo "<stdin>", linha 1 [x, x**2


for x in range(6)]
^^^^^^^

SyntaxError: você esqueceu os parênteses ao redor do alvo de compreensão? >>> # nivela uma lista usando um
listcomp com dois 'for' >>> vec = [[1,2,3], [4,5,6], [7,8,9]] >>> [num para elem em vec
para num em elem]

[1, 2, 3, 4, 5, 6, 7, 8, 9]

As compreensões de lista podem conter expressões complexas e funções aninhadas:

>>> from math import pi >>>


[str(round(pi, i)) for i in range(1, 6)] ['3.1', '3.14', '3.142', '3.1416',
'3.14159' ]

40 Capítulo 5. Estruturas de Dados


Machine Translated by Google

Tutorial do Python, versão 3.11.3

5.1.4 Compreensões de lista aninhada

A expressão inicial em uma compreensão de lista pode ser qualquer expressão arbitrária, incluindo outra compreensão de lista.

Considere o seguinte exemplo de uma matriz 3x4 implementada como uma lista de 3 listas de comprimento 4:

>>> matriz = [
... [1, 2, 3, 4], [5, 6, 7,
... 8], [9, 10, 11, 12],
...
... ]

A seguinte compreensão de lista transporá linhas e colunas:

>>> [[row[i] for row in matrix] for i in range(4)] [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4,
8, 12]]

Como vimos na seção anterior, a compreensão da lista interna é avaliada no contexto do for que a segue, então este exemplo é equivalente a:

>>> transposto = [] >>> para


i no intervalo(4):
... transposed.append([row[i] para linha na matriz])
...
>>> transposto [[1, 5,
9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

que, por sua vez, é o mesmo que:

>>> transposed = [] >>> for


i in range(4): # as 3 linhas a
... seguir implementam a listcomp aninhada transposed_row = [] for row in matrix:
...
...
... transposed_row.append(row[i])
... transposed.append(transposed_row)
...
>>> transposto [[1, 5,
9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

No mundo real, você deve preferir funções integradas a instruções de fluxo complexas. A função zip() faria um ótimo trabalho para este caso de
uso:

>>> lista(zip(*matriz)) [(1, 5, 9), (2,


6, 10), (3, 7, 11), (4, 8, 12)]

Consulte Descompactando listas de argumentos para obter detalhes sobre o asterisco nesta linha.

5.1. Mais sobre listas 41


Machine Translated by Google

Tutorial do Python, versão 3.11.3

5.2 A declaração del

Existe uma maneira de remover um item de uma lista dado seu índice em vez de seu valor: a instrução del. Isso difere do método pop()
que retorna um valor. A instrução del também pode ser usada para remover fatias de uma lista ou limpar a lista inteira (o que fizemos
anteriormente atribuindo uma lista vazia à fatia). Por exemplo:

>>> a = [-1, 1, 66,25, 333, 333, 1234,5] >>> del a[0]

>>> um
[1, 66.25, 333, 333, 1234.5] >>> del a[2:4]

>>> um
[1, 66.25, 1234.5] >>> del
a[:]
>>> um
[]

del também pode ser usado para excluir variáveis inteiras:

>>> de um

Referenciar o nome a doravante é um erro (pelo menos até que outro valor seja atribuído a ele). Encontraremos outros usos para del mais
tarde.

5.3 Tuplas e Sequências

Vimos que listas e strings têm muitas propriedades comuns, como operações de indexação e divisão. Eles são dois exemplos de tipos de
dados de sequência (consulte typesseq). Como o Python é uma linguagem em evolução, outros tipos de dados de sequência podem ser
adicionados. Há também outro tipo de dados de sequência padrão: a tupla.

Uma tupla consiste em um número de valores separados por vírgulas, por exemplo:

>>> t = 12345, 54321, 'olá!' >>> t[0]

12345
>>> t
(12345, 54321, 'olá!')
>>> # Tuplas podem ser aninhadas: ... u = t,
(1, 2, 3, 4, 5)
>>> você
((12345, 54321, 'olá!'), (1, 2, 3, 4, 5))
>>> # Tuplas são imutáveis: ... t[0] = 88888
Traceback (última
chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
TypeError: objeto 'tuple' não suporta atribuição de item >>> # mas eles podem conter objetos
mutáveis: v = ([1, 2, 3], [3, 2, 1])
...
>>> v
([1, 2, 3], [3, 2, 1])

Como você pode ver, na saída, as tuplas são sempre colocadas entre parênteses, para que as tuplas aninhadas sejam interpretadas
corretamente; eles podem ser inseridos com ou sem parênteses, embora frequentemente os parênteses sejam necessários de qualquer
maneira (se a tupla fizer parte de uma expressão maior). Não é possível atribuir itens individuais de uma tupla, mas é possível criar tuplas
que contenham objetos mutáveis, como listas.

42 Capítulo 5. Estruturas de Dados


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Embora as tuplas possam parecer semelhantes às listas, elas geralmente são usadas em diferentes situações e para diferentes propósitos. As tuplas são
imutáveis e geralmente contêm uma sequência heterogênea de elementos que são acessados via unpacking (veja mais adiante nesta seção) ou indexação
(ou mesmo por atributo no caso de namedtuples). As listas são mutáveis e seus elementos geralmente são homogêneos e são acessados por iteração na
lista.

Um problema especial é a construção de tuplas contendo 0 ou 1 itens: a sintaxe tem algumas peculiaridades extras para acomodá-las. Tuplas vazias são
construídas por um par de parênteses vazio; uma tupla com um item é construída seguindo um valor com uma vírgula (não é suficiente colocar um único
valor entre parênteses). Feio, mas eficaz. Por exemplo:

>>> vazio = () >>>


singleton = 'olá', >>> len(vazio) 0 # <-- observe a vírgula final

>>> len(singleton)
1
>>> singleton ('olá',)

A instrução t = 12345, 54321, 'olá!' é um exemplo de empacotamento de tuplas: os valores 12345, 54321 e 'hello!' são agrupados em uma tupla. A operação
inversa também é possível:

>>> x, y, z = t

Isso é chamado, apropriadamente, de desempacotamento de sequência e funciona para qualquer sequência no lado direito. A descompactação da
sequência requer que haja tantas variáveis no lado esquerdo do sinal de igual quantos sejam os elementos na sequência.
Observe que a atribuição múltipla é, na verdade, apenas uma combinação de empacotamento de tupla e desempacotamento de sequência.

5.4 Conjuntos

Python também inclui um tipo de dados para conjuntos. Um conjunto é uma coleção não ordenada sem elementos duplicados. Os usos básicos incluem
testes de associação e eliminação de entradas duplicadas. Objetos de conjunto também suportam operações matemáticas como união, interseção,
diferença e diferença simétrica.

Chaves ou a função set() podem ser usadas para criar conjuntos. Observação: para criar um conjunto vazio, você deve usar set(), não {}; o último cria um
dicionário vazio, uma estrutura de dados que discutiremos na próxima seção.

Segue uma breve demonstração:

>>> cesta = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} # mostra que duplicatas foram removidas >>>
print(basket) {'orange', ' banana', 'pêra', 'maçã'} >>> 'laranja' na cesta

# teste rápido de associação


Verdadeiro

>>> 'crabgrass' na cesta


Falso

>>> # Demonstra operações de conjunto em letras únicas de duas palavras


...
>>> a = set('abracadabra') >>> b =
set('alacazam')
>>> um # letras únicas em um
{'a', 'r', 'b', 'c', 'd'} >>> a - b
# letras em a mas não em b
{'r', 'd', 'b'} >>> a | b {'a',
'c', 'r', 'd', 'b', # letras em a ou b ou ambos
'm', 'z', 'l'}
(continua na próxima página)

5.4. Conjuntos 43
Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


>>> a & b # letras em a e b
{'a', 'c'}
>>> um ^
b # letras em a ou b, mas não em ambos
{'r', 'd', 'b', 'm', 'z', 'l'}

Da mesma forma que as compreensões de lista, as compreensões de conjunto também são suportadas:

>>> a = {x para x em 'abracadabra' se x não estiver em 'abc'}


>>> um
{'r', 'd'}

5.5 Dicionários

Outro tipo de dados útil incorporado ao Python é o dicionário (consulte mapeamento de tipos). Às vezes, os dicionários são encontrados em outros
idiomas como “memórias associativas” ou “matrizes associativas”. Ao contrário das sequências, que são indexadas por um intervalo de números, os
dicionários são indexados por chaves, que podem ser de qualquer tipo imutável; strings e números sempre podem ser chaves.
As tuplas podem ser usadas como chaves se contiverem apenas strings, números ou tuplas; se uma tupla contém qualquer objeto mutável direta ou
indiretamente, ela não pode ser usada como uma chave. Você não pode usar listas como chaves, pois as listas podem ser modificadas no local usando
atribuições de índice, atribuições de fatias ou métodos como append() e extend().

É melhor pensar em um dicionário como um conjunto de chaves: pares de valores, com a exigência de que as chaves sejam únicas (dentro de um
dicionário). Um par de chaves cria um dicionário vazio: {}. Colocar uma lista separada por vírgulas de pares de chave:valor dentro das chaves adiciona
os pares de chave:valor iniciais ao dicionário; esta também é a forma como os dicionários são escritos na saída.

As principais operações em um dicionário são armazenar um valor com alguma chave e extrair o valor fornecido pela chave. Também é possível excluir
um par chave:valor com del. Se você armazenar usando uma chave que já está em uso, o valor antigo associado a essa chave será esquecido. É um
erro extrair um valor usando uma chave inexistente.

A execução de list(d) em um dicionário retorna uma lista de todas as chaves usadas no dicionário, na ordem de inserção (se você quiser classificar,
basta usar sorted(d)). Para verificar se uma única chave está no dicionário, use a palavra-chave in.

Aqui está um pequeno exemplo usando um dicionário:

>>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido'] = 4127

>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127} >>> tel['jack'] 4098

>>> del tel['sape'] >>> tel['irv']


= 4127 >>> tel

{'jack': 4098, 'guido': 4127, 'irv': 4127} >>> list(tel) ['jack', 'guido', 'irv']
>>> sorted(tel)
['guido' , 'irv', 'jack'] >>> 'guido' in tel

Verdadeiro

>>> 'jack' não está no tel


Falso

O construtor dict() constrói dicionários diretamente de sequências de pares chave-valor:

44 Capítulo 5. Estruturas de Dados


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'guido': 4127, 'jack': 4098}

Além disso, as compreensões dict podem ser usadas para criar dicionários a partir de chaves arbitrárias e expressões de valor:

>>> {x: x**2 para x em (2, 4, 6)} {2: 4, 4: 16, 6: 36}

Quando as chaves são strings simples, às vezes é mais fácil especificar pares usando argumentos de palavra-chave:

>>> dict(sape=4139, guido=4127, jack=4098) {'sape': 4139, 'guido':


4127, 'jack': 4098}

5.6 Técnicas de Looping

Ao percorrer os dicionários, a chave e o valor correspondente podem ser recuperados ao mesmo tempo usando o método items().

>>> knights = {'gallahad': 'o puro', 'robin': 'o bravo'} >>> for k, v in knights.items(): print(k, v)

...
...
gallahad o puro robin o
bravo

Ao percorrer uma sequência, o índice de posição e o valor correspondente podem ser recuperados ao mesmo tempo usando a função
enumerate().

>>> for i, v in enumerate(['tic', 'tac', 'toe']):


... imprimir(i, v)
...
0 tique
1 tac
2 dedos

Para percorrer duas ou mais sequências ao mesmo tempo, as entradas podem ser combinadas com a função zip().

>>> perguntas = ['nome', 'busca', 'cor favorita'] >>> respostas = ['lancelot', 'o santo graal', 'azul']
>>> for q, a in zip(perguntas , respostas): print('Qual é o seu {0}? É {1}.'.format(q, a))

...
...
Qual o seu nome? É lancelote.
Qual é a sua busca? É o Santo Graal.
Qual a sua cor preferida? Isso é azul.

Para fazer um loop em uma sequência ao contrário, primeiro especifique a sequência em uma direção direta e, em seguida, chame a função
reversed().

>>> for i in reverse(range(1, 10, 2)): print(i)


...
...
9
7
(continua na próxima página)

5.6. Técnicas de Looping 45


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


5
3
1

Para percorrer uma sequência em ordem de classificação, use a função sorted() que retorna uma nova lista de classificação, deixando
a fonte inalterada.

>>> cesta = ['maçã', 'laranja', 'maçã', 'pêra', 'laranja', 'banana'] >>> for i in sorted(cesta): print(i)

...
...
maçã
maçã
banana
laranja
laranja
pera

Usar set() em uma sequência elimina elementos duplicados. O uso de sorted() em combinação com set() em uma sequência é uma
maneira idiomática de repetir elementos exclusivos da sequência em ordem de classificação.

>>> cesta = ['maçã', 'laranja', 'maçã ', 'pêra', 'laranja', 'banana'] >>> for f in sorted(set(cesta)): print(f)

...
...
maçã
banana
laranja
pera

Às vezes, é tentador alterar uma lista enquanto você está passando por ela; no entanto, geralmente é mais simples e seguro criar uma
nova lista.

>>> import math >>>


raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8] >>> filtered_data = [] >>> for value in raw_data:

... se não math.isnan(valor):


... dados_filtrados.append(valor)
...
>>> dados_filtrados [56,2,
51,7, 55,3, 52,5, 47,8]

5.7 Mais sobre Condições

As condições usadas nas instruções while e if podem conter qualquer operador, não apenas comparações.

Os operadores de comparação in e not in são testes de associação que determinam se um valor está (ou não está) em um contêiner.
Os operadores é e não comparam se dois objetos são realmente o mesmo objeto. Todos os operadores de comparação têm a mesma
prioridade, que é inferior à de todos os operadores numéricos.

As comparações podem ser encadeadas. Por exemplo, a < b == c testa se a é menor que b e, além disso, b é igual a c.

As comparações podem ser combinadas usando os operadores booleanos and e or, e o resultado de uma comparação (ou de qualquer
outra expressão booleana) pode ser negado com not. Estes têm prioridades mais baixas do que os operadores de comparação; entre

46 Capítulo 5. Estruturas de Dados


Machine Translated by Google

Tutorial do Python, versão 3.11.3

deles, not tem a prioridade mais alta e/ou a mais baixa, de modo que A e não B ou C é equivalente a (A e (não B)) ou C. Como sempre,
parênteses podem ser usados para expressar a composição desejada.

Os operadores booleanos and e or são chamados de operadores de curto-circuito : seus argumentos são avaliados da esquerda para
a direita e a avaliação é interrompida assim que o resultado é determinado. Por exemplo, se A e C são verdadeiros, mas B é falso, A e
B e C não avaliam a expressão C. Quando usado como um valor geral e não como um Booleano, o valor de retorno de um operador de
curto-circuito é o último argumento avaliado.

É possível atribuir o resultado de uma comparação ou outra expressão booleana a uma variável. Por exemplo,

>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance' >>> non_null = string1 ou string2 ou
string3 >>> non_null

'Trondheim'

Observe que em Python, ao contrário de C, a atribuição dentro de expressões deve ser feita explicitamente com o operador morsa :=.
Isso evita uma classe comum de problemas encontrados em programas C: digitar = em uma expressão quando == era pretendido.

5.8 Comparando Sequências e Outros Tipos

Os objetos de sequência normalmente podem ser comparados a outros objetos com o mesmo tipo de sequência. A comparação usa
ordenação gráfica do léxico : primeiro os dois primeiros itens são comparados e, se eles diferirem, isso determinará o resultado da
comparação; se forem iguais, os próximos dois itens são comparados e assim por diante, até que uma das sequências se esgote. Se
dois itens a serem comparados forem sequências do mesmo tipo, a comparação lexicográfica é realizada recursivamente. Se todos os
itens de duas sequências forem iguais, as sequências são consideradas iguais. Se uma sequência é uma subsequência inicial da outra,
a sequência mais curta é a menor (menor). A ordenação lexicográfica de strings usa o número de ponto de código Unicode para ordenar
caracteres individuais. Alguns exemplos de comparações entre sequências do mesmo tipo:

(1, 2, 3) [1, < (1, 2, 4) < [1,


2, 3] 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) (1, 2) (1,
2, 3) (1, 2, ('aa', < (1, 2, 4) < (1,
'ab') ) 2, -1) == (1,0, 2,0,
3,0) < (1, 2, ('abc', 'a'), 4)

Observe que comparar objetos de tipos diferentes com < ou > é legal desde que os objetos tenham métodos de comparação
apropriados. Por exemplo, tipos numéricos mistos são comparados de acordo com seu valor numérico, então 0 é igual a 0,0, etc.
Caso contrário, em vez de fornecer uma ordem arbitrária, o interpretador gerará uma exceção TypeError.

5.8. Comparando sequências e outros tipos 47


Machine Translated by Google

Tutorial do Python, versão 3.11.3

48 Capítulo 5. Estruturas de Dados


Machine Translated by Google

CAPÍTULO

SEIS

MÓDULOS

Se você sair do interpretador Python e entrar novamente, as definições feitas (funções e variáveis) serão perdidas.
Portanto, se você deseja escrever um programa um pouco mais longo, é melhor usar um editor de texto para preparar a entrada para o
interpretador e executá-lo com esse arquivo como entrada. Isso é conhecido como criar um script. À medida que seu programa fica mais
longo, você pode querer dividi-lo em vários arquivos para facilitar a manutenção. Você também pode querer usar uma função útil que
você escreveu em vários programas sem copiar sua definição em cada programa.

Para suportar isso, o Python tem uma maneira de colocar definições em um arquivo e usá-las em um script ou em uma instância
interativa do interpretador. Esse arquivo é chamado de módulo; as definições de um módulo podem ser importadas para outros módulos
ou para o módulo principal (a coleção de variáveis a que você tem acesso em um script executado no nível superior e no modo calculadora).

Um módulo é um arquivo contendo definições e instruções do Python. O nome do arquivo é o nome do módulo com o sufixo .py
anexado. Dentro de um módulo, o nome do módulo (como uma string) está disponível como o valor da variável global __name__.
Por exemplo, use seu editor de texto favorito para criar um arquivo chamado fibo.py no diretório atual com o seguinte
conteúdo:

# Módulo de números de Fibonacci

def fib(n): # escreve a série de Fibonacci até n a, b = 0, 1 while


a < n:

print(a, end=' ') a, b = b, a+b

imprimir()

def fib2(n): # retorna a série Fibonacci até n resultado = [] a, b = 0, 1 while a < n:

result.append(a) a, b = b,
a+b
resultado de retorno

Agora entre no interpretador Python e importe este módulo com o seguinte comando:

>>> importar fibo

Isso não adiciona os nomes das funções definidas em fibo diretamente ao namespace atual (consulte Python Scopes and Namespaces
para obter mais detalhes); ele apenas adiciona o nome do módulo fibo lá. Usando o nome do módulo, você pode acessar as funções:

>>> fibo.fib(1000) 0 1 1 2 3 5
8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100) [0, 1, 1, 2,
3, 5, 8, 13, 21, 34, 55, 89]
(continua na próxima página)

49
Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

>>> fibo.__name__ 'fibo'

Se você pretende usar uma função com frequência, pode atribuí-la a um nome local:

>>> fib = fibo.fib


>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

6.1 Mais sobre Módulos

Um módulo pode conter instruções executáveis, bem como definições de função. Essas instruções destinam-se a inicializar o módulo. Eles são
executados apenas na primeira vez que o nome do módulo é encontrado em uma instrução de importação.1 (Eles também são executados se o
arquivo for executado como um script.)

Cada módulo tem seu próprio namespace privado, que é usado como namespace global por todas as funções definidas no módulo.
Assim, o autor de um módulo pode usar variáveis globais no módulo sem se preocupar com conflitos acidentais com as variáveis globais do
usuário. Por outro lado, se você souber o que está fazendo, pode tocar nas variáveis globais de um módulo com a mesma notação usada para se
referir às suas funções, modname.itemname.

Os módulos podem importar outros módulos. É comum, mas não obrigatório, colocar todas as instruções de importação no início de um módulo
(ou script, nesse caso). Os nomes dos módulos importados, se colocados no nível superior de um módulo (fora de quaisquer funções ou classes),
são adicionados ao namespace global do módulo.

Há uma variante da instrução import que importa nomes de um módulo diretamente para o namespace do módulo de importação. Por exemplo:

>>> de fibo import fib, fib2 >>> fib(500)

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Isso não introduz o nome do módulo do qual as importações são feitas no namespace local (portanto, no exemplo, fibo não está definido).

Existe até uma variante para importar todos os nomes que um módulo define:

>>> from fibo import * >>> fib(500)


0 1 1 2 3 5 8 13 21
34 55 89 144 233 377

Isso importa todos os nomes, exceto aqueles que começam com sublinhado (_). Na maioria dos casos, os programadores Python não usam esse
recurso, pois ele introduz um conjunto desconhecido de nomes no interpretador, possivelmente ocultando algumas coisas que você já definiu.

Observe que, em geral, a prática de importar * de um módulo ou pacote é desaprovada, pois muitas vezes causa código mal legível. No entanto,
não há problema em usá-lo para economizar digitação em sessões interativas.

Se o nome do módulo for seguido por as, o nome após as será vinculado diretamente ao módulo importado.

>>> import fibo as fib >>>


fib.fib(500) 0 1 1 2 3 5 8
13 21 34 55 89 144 233 377

1 Na verdade, as definições de função também são 'declarações' que são 'executadas'; a execução de uma definição de função em nível de módulo adiciona o nome da função a

o namespace global do módulo.

50 Capítulo 6. Módulos
Machine Translated by Google

Tutorial do Python, versão 3.11.3

Isso é efetivamente importar o módulo da mesma forma que o import fibo fará, com a única diferença de estar disponível como fib.

Também pode ser usado ao utilizar from com efeitos semelhantes:

>>> de fibo import fib como fibonacci >>> fibonacci(500)

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Observação: por motivos de eficiência, cada módulo é importado apenas uma vez por sessão do intérprete. Portanto, se você alterar seus módulos,
deverá reiniciar o interpretador – ou, se for apenas um módulo que deseja testar interativamente, use o importlib. reload(), por exemplo, import
importlib; importlib.reload(modulename).

6.1.1 Executando módulos como scripts

Quando você executa um módulo Python com

python fibo.py <argumentos>

o código do módulo será executado, como se você o tivesse importado, mas com o __name__ definido como "__main__". Isso significa que,
adicionando este código no final do seu módulo:

if __name__ == "__main__": import


sys
fib(int(sys.argv[1]))

você pode tornar o arquivo utilizável como um script, bem como um módulo importável, porque o código que analisa a linha de comando só é
executado se o módulo for executado como o arquivo “principal”:

$ python fibo.py 50 0 1 1 2 3
5 8 13 21 34

Se o módulo for importado, o código não é executado:

>>> importar fibo


>>>

Isso geralmente é usado para fornecer uma interface de usuário conveniente para um módulo ou para fins de teste (executar o módulo como um
script executa um conjunto de testes).

6.1.2 O caminho de pesquisa do módulo

Quando um módulo denominado spam é importado, o interpretador primeiro procura um módulo integrado com esse nome. Esses nomes de módulo
estão listados em sys.builtin_module_names. Se não for encontrado, ele procurará um arquivo chamado spam.py em uma lista de diretórios fornecida
pela variável sys.path. sys.path é inicializado a partir destes locais:

• O diretório que contém o script de entrada (ou o diretório atual quando nenhum arquivo é especificado).

• PYTHONPATH (uma lista de nomes de diretórios, com a mesma sintaxe da variável de shell PATH).

• O padrão dependente da instalação (por convenção, incluindo um diretório de pacotes do site, manipulado pelo site
módulo).

6.1. Mais sobre Módulos 51


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Mais detalhes estão em sys-path-init.

Nota: Em sistemas de arquivos que suportam links simbólicos, o diretório que contém o script de entrada é calculado após o link simbólico
ser seguido. Em outras palavras, o diretório que contém o link simbólico não é adicionado ao caminho de pesquisa do módulo.

Após a inicialização, os programas Python podem modificar sys.path. O diretório que contém o script que está sendo executado é colocado
no início do caminho de pesquisa, à frente do caminho da biblioteca padrão. Isso significa que os scripts nesse diretório serão carregados em
vez de módulos com o mesmo nome no diretório da biblioteca. Isso é um erro, a menos que a substituição seja pretendida.
Consulte a seção Módulos padrão para obter mais informações.

6.1.3 Arquivos Python “compilados”

Para acelerar o carregamento dos módulos, o Python armazena em cache a versão compilada de cada módulo no diretório __pycache__ sob
o nome module.version.pyc, onde a versão codifica o formato do arquivo compilado; geralmente contém o número da versão do Python. Por
exemplo, na versão 3.3 do CPython, a versão compilada de spam.py seria armazenada em cache como __pycache__/spam.cpython-33.pyc.
Essa convenção de nomenclatura permite a coexistência de módulos compilados de diferentes lançamentos e diferentes versões do Python.

O Python verifica a data de modificação da fonte em relação à versão compilada para ver se está desatualizada e precisa ser recompilada.
Este é um processo completamente automático. Além disso, os módulos compilados são independentes de plataforma, portanto, a mesma
biblioteca pode ser compartilhada entre sistemas com arquiteturas diferentes.

O Python não verifica o cache em duas circunstâncias. Primeiro, ele sempre recompila e não armazena o resultado do módulo carregado
diretamente da linha de comando. Em segundo lugar, ele não verifica o cache se não houver módulo de origem.
Para oferecer suporte a uma distribuição não fonte (somente compilada), o módulo compilado deve estar no diretório de origem e não deve
haver um módulo de origem.

Algumas dicas para especialistas:

• Você pode usar as opções -O ou -OO no comando Python para reduzir o tamanho de um módulo compilado. A opção -O remove as
declarações assert, a opção -OO remove as declarações assert e as strings __doc__. Como alguns programas podem contar com a
disponibilidade desses recursos, você só deve usar essa opção se souber o que está fazendo. Os módulos “otimizados” têm uma tag
de opção e geralmente são menores. Versões futuras podem alterar os efeitos da otimização.

• Um programa não roda mais rápido quando é lido de um arquivo .pyc do que quando é lido de um arquivo .py; a única coisa mais rápida
nos arquivos .pyc é a velocidade com que são carregados.

• O módulo compileall pode criar arquivos .pyc para todos os módulos em um diretório.

• Há mais detalhes sobre esse processo, incluindo um fluxograma das decisões, no PEP 3147.

6.2 Módulos Padrão


O Python vem com uma biblioteca de módulos padrão, descrita em um documento separado, a Python Library Reference (“Library Reference”
a seguir). Alguns módulos são construídos no interpretador; eles fornecem acesso a operações que não fazem parte do núcleo da linguagem,
mas, no entanto, são incorporadas, seja por eficiência ou para fornecer acesso a primitivas do sistema operacional, como chamadas de
sistema. O conjunto desses módulos é uma opção de configuração que também depende da plataforma subjacente. Por exemplo, o módulo
winreg é fornecido apenas em sistemas Windows. Um módulo em particular merece alguma atenção: sys, que está embutido em todo
interpretador Python. As variáveis sys.ps1 e sys.ps2 definem as strings usadas como prompts primários e secundários:

52 Capítulo 6. Módulos
Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> importar sys >>>


sys.ps1
'>>> '
>>> sys.ps2 '... '

>>> sys.ps1 = 'C> '


C> print('Eca!')
Que nojo!
C>

Essas duas variáveis só são definidas se o interpretador estiver em modo interativo.

A variável sys.path é uma lista de strings que determina o caminho de pesquisa do interpretador para módulos. Ele é inicializado para
um caminho padrão obtido da variável de ambiente PYTHONPATH ou de um padrão interno se PYTHONPATH não estiver definido.
Você pode modificá-lo usando operações de lista padrão:

>>> import sys >>>


sys.path.append('/ufs/guido/lib/python')

6.3 A função dir()

A função interna dir() é usada para descobrir quais nomes um módulo define. Ele retorna uma lista ordenada de strings:

>>> importar fibo, sys >>>


dir(fibo)
['__name__', 'fib', 'fib2'] >>> dir(sys)
['__breakpointhook__',
'__displayhook__', '__doc__', '__excepthook__',
'__interactivehook__', '__loader__', '__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__',
'__unraisablehook__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework ',
'_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook', 'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix',
'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook',
'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags ', 'float_info',
'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth', 'getallocatedblocks', 'getdefaultencoding',
'getdlopenflags', 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof',
'getswitchinterval', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'is_finalizing', 'last_traceback',
'last_type', 'last_value', 'maxsize ', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix',
'ps1', 'ps2', 'pycache_prefix', 'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth',
'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info',
'unraisablehook', 'version', 'version_info ', 'opções de aviso']

Sem argumentos, dir() lista os nomes que você definiu atualmente:

>>> a = [1, 2, 3, 4, 5] >>> importar


fibo >>> fib = fibo.fib

(continua na próxima página)

6.3. A função dir() 53


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


>>> dir()
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']

Note que ele lista todos os tipos de nomes: variáveis, módulos, funções, etc.

dir() não lista os nomes de funções e variáveis internas. Se você quiser uma lista deles, eles são definidos nos módulos padrão integrados:

>>> importar builtins >>> dir


(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
'EOFError', 'Reticências', 'EnvironmentError', 'Exceção', 'Falso',
'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',
'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
'MemoryError', 'NameError', 'Nenhum', 'NotADirectoryError', 'NotImplemented',
'NotImplementedError', 'OSError', 'OverflowError',
'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__',
'__name__', '__package__', 'abs', 'all', 'any ', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod',
'compile', 'complex', 'copyright', 'créditos', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter',
'float', 'format', 'frozenset', 'getattr ', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance',
'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord',
'pow ', 'print', 'propriedade', 'sair', 'intervalo', 'repr', 'invertido', 'redondo', 'definir', 'setattr', 'fatia', 'classificado', 'método
estático', 'str', 'soma', 'super', 'tupla', 'tipo', 'vars', 'zip']

6.4 Pacotes
Os pacotes são uma forma de estruturar o namespace do módulo do Python usando “nomes de módulo pontilhados”. Por exemplo, o
nome do módulo AB designa um submódulo chamado B em um pacote chamado A. Assim como o uso de módulos evita que os autores
de diferentes módulos tenham que se preocupar com os nomes das variáveis globais uns dos outros, o uso de nomes de módulo
pontilhados salva os autores de pacotes de vários módulos, como NumPy ou Pillow, de se preocupar com os nomes dos módulos uns dos outros.

Suponha que você queira projetar uma coleção de módulos (um “pacote”) para a manipulação uniforme de arquivos de som e dados de
som. Existem muitos formatos de arquivo de som diferentes (geralmente reconhecidos por sua extensão, por exemplo: .wav, .aiff, .au),
então você pode precisar criar e manter uma coleção crescente de módulos para a conversão entre os vários formatos de arquivo.
Existem também muitas operações diferentes que você pode querer realizar em dados de som (como mixar, adicionar eco, aplicar uma
função de equalizador, criar um efeito estéreo artificial), então, além disso, você estará escrevendo um fluxo interminável de módulos
para executar essas operações. Aqui está uma estrutura possível para o seu pacote (expressa em termos de um sistema de arquivos
hierárquico):

54 Capítulo 6. Módulos
Machine Translated by Google

Tutorial do Python, versão 3.11.3

som/ Pacote de nível superior


__init__.py formatos/ Inicializar o pacote de som
__init__.py Subpacote para conversões de formato de arquivo
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py auwrite.py

...
efeitos/ Subpacote para efeitos sonoros
__init__.py echo.py
surround.py

reverse.py
...
filtros/ Subpacote para filtros
__init__.py equalizer.py
vocoder.py
karaoke.py

...

Ao importar o pacote, o Python pesquisa nos diretórios em sys.path procurando o subdiretório do pacote.

Os arquivos __init__.py são necessários para fazer com que o Python trate os diretórios que contêm o arquivo como pacotes. Isso evita
que diretórios com um nome comum, como string, ocultem acidentalmente módulos válidos que ocorrem posteriormente no caminho de
pesquisa do módulo. No caso mais simples, __init__.py pode ser apenas um arquivo vazio, mas também pode executar o código de
inicialização para o pacote ou definir a variável __all__, descrita posteriormente.

Os usuários do pacote podem importar módulos individuais do pacote, por exemplo:

importar som.efeitos.eco

Isso carrega o submódulo sound.effects.echo. Deve ser referenciado com seu nome completo.

sound.effects.echo.echofilter(entrada, saída, atraso=0,7, atten=4)

Uma forma alternativa de importar o submódulo é:

de eco de importação de som.efeitos

Isso também carrega o submódulo echo, e o disponibiliza sem seu prefixo de pacote, então pode ser usado da seguinte forma:

echo.echofilter(entrada, saída, atraso=0,7, atten=4)

Ainda outra variação é importar a função ou variável desejada diretamente:

from sound.effects.echo import echofilter

Novamente, isso carrega o submódulo echo, mas torna sua função echofilter() diretamente disponível:

echofilter(entrada, saída, atraso=0,7, atten=4)

Observe que ao usar from package import item, o item pode ser um submódulo (ou subpacote) do pacote ou algum outro nome definido
no pacote, como uma função, classe ou variável. A instrução de importação primeiro testa

6.4. Pacotes 55
Machine Translated by Google

Tutorial do Python, versão 3.11.3

se o item está definido no pacote; caso contrário, ele assume que é um módulo e tenta carregá-lo. Se não conseguir localizá-lo, uma
exceção ImportError será lançada.

Ao contrário, ao usar sintaxe como import item.subitem.subsubitem, cada item, exceto o último, deve ser um pacote; o último item pode
ser um módulo ou um pacote mas não pode ser uma classe ou função ou variável definida no item anterior.

6.4.1 Importando * de um pacote


Agora, o que acontece quando o usuário escreve a partir da importação de sound.effects *? Idealmente, seria de esperar que isso de
alguma forma vá para o sistema de arquivos, encontre quais submódulos estão presentes no pacote e importe todos eles. Isso pode
levar muito tempo e a importação de submódulos pode ter efeitos colaterais indesejados que só devem ocorrer quando o submódulo
for explicitamente importado.

A única solução é o autor do pacote fornecer um índice explícito do pacote. A instrução import usa a seguinte convenção: se o código
__init__.py de um pacote define uma lista chamada __all__, ela é considerada a lista de nomes de módulos que devem ser importados
quando from package import * é encontrado. Cabe ao autor do pacote manter esta lista atualizada quando uma nova versão do pacote
é lançada. Os autores de pacotes também podem decidir não oferecer suporte, caso não vejam um uso para importar * de seu pacote.
Por exemplo, o arquivo sound/effects/ __init__.py pode conter o seguinte código:

__all__ = ["eco", "surround", "reverse"]

Isso significaria que from sound.effects import * importaria os três submódulos nomeados do pacote sound.effects.

Se __all__ não for definido, a instrução from sound.effects import * não importa todos os submódulos do pacote sound.effects para o
namespace atual; ele apenas garante que o pacote sound.effects foi importado (possivelmente executando qualquer código de
inicialização em __init__.py) e então importa quaisquer nomes definidos no pacote. Isso inclui quaisquer nomes definidos (e submódulos
explicitamente carregados) por __init__.py. Ele também inclui quaisquer submódulos do pacote que foram carregados explicitamente
por instruções de importação anteriores. Considere este código:

importar som.efeitos.echo importar


som.efeitos.surround de som.efeitos
importar *

Neste exemplo, os módulos echo e surround são importados no namespace atual porque são definidos no pacote sound.effects quando
a instrução from...import é executada. (Isso também funciona quando __all__ é definido.)

Embora certos módulos sejam projetados para exportar apenas nomes que seguem certos padrões quando você usa import *, ainda é
considerado uma prática ruim no código de produção.

Lembre-se, não há nada de errado em usar from package import specific_submodule! Na verdade, esta é a notação recomendada, a
menos que o módulo de importação precise usar submódulos com o mesmo nome de pacotes diferentes.

56 Capítulo 6. Módulos
Machine Translated by Google

Tutorial do Python, versão 3.11.3

6.4.2 Referências Intrapacote

Quando os pacotes são estruturados em subpacotes (como no pacote de som no exemplo), você pode usar importações absolutas para
se referir a submódulos de pacotes irmãos. Por exemplo, se o módulo sound.filters.vocoder precisar usar o módulo echo no pacote
sound.effects, ele pode usar from sound.effects import echo.

Você também pode escrever importações relativas, com a forma de nome de importação do módulo from da instrução de importação.
Essas importações usam pontos à esquerda para indicar os pacotes atuais e principais envolvidos na importação relativa. No módulo
surround, por exemplo, você pode usar:

de . importar eco de ..
importar formatos de ..filters
importar equalizador

Observe que as importações relativas são baseadas no nome do módulo atual. Como o nome do módulo principal é sempre "__main__",
os módulos destinados a serem usados como o módulo principal de um aplicativo Python devem sempre usar importações absolutas.

6.4.3 Pacotes em vários diretórios

Os pacotes suportam mais um atributo especial, __path__. Isso é inicializado para ser uma lista contendo o nome do diretório que contém
o __init__.py do pacote antes que o código desse arquivo seja executado. Esta variável pode ser modificada; isso afeta pesquisas futuras
de módulos e subpacotes contidos no pacote.

Embora esse recurso não seja necessário com frequência, ele pode ser usado para estender o conjunto de módulos encontrados em um pacote.

6.4. Pacotes 57
Machine Translated by Google

Tutorial do Python, versão 3.11.3

58 Capítulo 6. Módulos
Machine Translated by Google

CAPÍTULO

SETE

ENTRADA E SAÍDA

Existem várias maneiras de apresentar a saída de um programa; os dados podem ser impressos em um formato legível por humanos ou gravados em
um arquivo para uso futuro. Este capítulo discutirá algumas das possibilidades.

7.1 Formatação de saída mais sofisticada

Até agora, encontramos duas maneiras de escrever valores: declarações de expressão e a função print(). (Uma terceira maneira é usar o método
write() de objetos de arquivo; o arquivo de saída padrão pode ser referenciado como sys.stdout. Consulte a Referência da Biblioteca para obter mais
informações sobre isso.)

Freqüentemente, você desejará mais controle sobre a formatação de sua saída do que simplesmente imprimir valores separados por espaços. Existem
várias maneiras de formatar a saída.

• Para usar strings literais formatadas, comece uma string com f ou F antes das aspas de abertura ou aspas triplas. Dentro dessa string, você
pode escrever uma expressão Python entre os caracteres { e } que podem se referir a variáveis ou valores literais.

>>> ano = 2016 >>> evento


= 'Referendo'
>>> f'Resultados do {ano} {evento}'
'Resultados do referendo de 2016'

• O método str.format() de strings requer mais esforço manual. Você ainda usará { e } para marcar onde uma variável será substituída e poderá
fornecer diretivas de formatação detalhadas, mas também precisará fornecer as informações a serem formatadas.

>>> yes_votes = 42_572_654 >>> no_votes =


43_132_495 >>> percent = yes_votes /
(yes_votes + no_votes)
>>> '{:-9} votos SIM {:2.2%}'.format(votos_sim, porcentagem)
'42572654 votos SIM 49,67%'

• Por fim, você mesmo pode fazer todo o manuseio de strings usando fatias de strings e operações de concatenação para criar qualquer layout
que você possa imaginar. O tipo string tem alguns métodos que executam operações úteis para preencher strings em uma determinada largura
de coluna.

Quando você não precisa de uma saída sofisticada, mas apenas deseja uma exibição rápida de algumas variáveis para fins de depuração, pode
converter qualquer valor em uma string com as funções repr() ou str().

A função str() destina-se a retornar representações de valores que são razoavelmente legíveis por humanos, enquanto repr() destina-se a gerar
representações que podem ser lidas pelo interpretador (ou forçará um SyntaxError se não houver sintaxe equivalente). Para objetos que não possuem
uma representação particular para consumo humano, str() retornará o mesmo

59
Machine Translated by Google

Tutorial do Python, versão 3.11.3

valor como repr(). Muitos valores, como números ou estruturas como listas e dicionários, têm a mesma representação usando qualquer
função. Strings, em particular, têm duas representações distintas.

Alguns exemplos:

>>> s = 'Olá, mundo.' >>> str(s)

'Olá Mundo.' >>> repr(s)

"'Olá, mundo.'" >>> str(1/7)


'0.14285714285714285'

>>> x = 10 * 3,25
>>> y = 200 * 200 >>> s = 'O
valor de x é ' + repr(x) + ', e y é ' + repr(y) + '...'
>>> estampa(s)
O valor de x é 32,5 e y é 40000...
>>> # O repr() de uma string adiciona aspas e barras invertidas: ... hello = 'hello, world\n' >>> hellos = repr(hello)
>>> print(hellos) 'hello, world\ n'

>>> # O argumento para repr() pode ser qualquer objeto Python: ... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs '))"

O módulo string contém uma classe Template que oferece ainda outra maneira de substituir valores em strings, usando espaços
reservados como $x e substituindo-os por valores de um dicionário, mas oferece muito menos controle da formatação.

7.1.1 Literais de string formatados

Os literais de string formatados (também chamados de f-strings para abreviar) permitem incluir o valor das expressões Python dentro
de uma string prefixando a string com f ou F e escrevendo expressões como {expression}.

Um especificador de formato opcional pode seguir a expressão. Isso permite maior controle sobre como o valor é formatado. O exemplo
a seguir arredonda pi para três casas após o decimal:

>>> import math >>>


print(f'O valor de pi é aproximadamente {math.pi:.3f}.')
O valor de pi é aproximadamente 3,142.

Passar um número inteiro após o ':' fará com que esse campo tenha um número mínimo de caracteres de largura. Isso é útil para alinhar
as colunas.

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} >>> for name, phone in table.items():

... print(f'{nome:10} ==> {telefone:10d}')


...
Sjoerd ==> 4127
Jack ==> 4098
Dcab ==> 7678

Outros modificadores podem ser usados para converter o valor antes de ser formatado. '!a' aplica ascii(), '!s' aplica str(), e '!r' aplica repr():

>>> animais = 'enguias'

>>> print(f'Meu hovercraft está cheio de {animais}.')


(continua na próxima página)

60 Capítulo 7. Entrada e Saída


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

Meu hovercraft está cheio de enguias. >>>


print(f'Meu hovercraft está cheio de {animais!r}.')
Meu hovercraft está cheio de enguias'.

O especificador = pode ser usado para expandir uma expressão para o texto da expressão, um sinal de igual e, em seguida, a representação da expressão
avaliada:

>>> bugs = 'baratas' >>>


contagem = 13
>>> area = 'sala de estar' >>>
print(f'Depurando {bugs=} {count=} {area=}')
Depuração de bugs='baratas' contagem=13 área='sala de estar'

Consulte expressões de autodocumentação para obter mais informações sobre o especificador =. Para obter uma referência sobre essas especificações de
formato, consulte o guia de referência para o formatspec.

7.1.2 O Método String format()


O uso básico do método str.format() se parece com isto:

>>> print('Somos os {} que dizem "{}!"'.format('cavaleiros', 'Ni'))


Nós somos os cavaleiros que dizem "Ni!"

Os colchetes e caracteres dentro deles (chamados campos de formato) são substituídos pelos objetos passados para o str. método forma(). Um número
entre colchetes pode ser usado para se referir à posição do objeto passado para o str. método forma().

>>> print('{0} and {1}'.format('spam', 'eggs')) spam e eggs >>> print('{1} and
{0}'.format('spam',
'ovos')) ovos e spam

Se argumentos de palavras-chave forem usados no método str.format(), seus valores serão referidos usando o nome do argumento.

>>> print('Este {comida} é {adjetivo}.'.format(


... comida='spam', adjetivo='absolutamente horrível'))
Este spam é absolutamente horrível.

Argumentos posicionais e palavras-chave podem ser combinados arbitrariamente:

>>> print('A história de {0}, {1}, e {outro}.'.format('Bill', 'Manfred',


... outro='Georg'))
A história de Bill, Manfred e Georg.

Se você tiver uma string de formato muito longa que não deseja dividir, seria bom se você pudesse referenciar as variáveis a serem formatadas por nome
em vez de por posição. Isso pode ser feito simplesmente passando o ditado e usando colchetes '[]' para acessar as chaves.

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print('Jack: {0[Jack]:d}; Sjoerd:
{0[Sjoerd]:d }; '
... 'Dcab: {0[Dcab]:d}'.format(tabela))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

Isso também pode ser feito passando o dicionário de tabelas como argumentos de palavra-chave com a notação **.

7.1. Formatação de saída mais sofisticada 61


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print('Jack: {Jack:d}; Sjoerd:
{Sjoerd:d}; Dcab: {Dcab :d}'.format(**tabela))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

Isso é particularmente útil em combinação com a função incorporada vars(), que retorna um dicionário contendo todas as variáveis locais.

Como exemplo, as linhas a seguir produzem um conjunto de colunas perfeitamente alinhadas, fornecendo números inteiros e seus quadrados e cubos:

>>> para x no intervalo(1, 11):


... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

Para obter uma visão geral completa da formatação de strings com str.format(), consulte formatstrings.

7.1.3 Formatação manual de strings

Aqui está a mesma tabela de quadrados e cubos, formatada manualmente:

>>> para x no intervalo(1, 11):


... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
... # Observe o uso de 'end' na linha anterior
... print(repr(x*x*x).rjust(4))
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

(Observe que o espaço entre cada coluna foi adicionado pela maneira como print() funciona: ele sempre adiciona espaços entre seus
argumentos.)

O método str.rjust() de objetos string justifica uma string à direita em um campo de uma determinada largura preenchendo-a com espaços à
esquerda. Existem métodos semelhantes str.ljust() e str.center(). Esses métodos não escrevem nada, apenas retornam uma nova string. Se
a string de entrada for muito longa, eles não a truncam, mas a retornam inalterada; isso vai atrapalhar o layout da coluna, mas geralmente é
melhor do que a alternativa, que seria mentir sobre um valor. (Se você realmente deseja truncamento, pode sempre adicionar uma operação
de divisão, como em x.ljust(n)[:n].)

Existe outro método, str.zfill(), que preenche uma string numérica à esquerda com zeros. Ele entende sobre sinais de mais e menos:

62 Capítulo 7. Entrada e Saída


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> '12'.zfill(5) '00012'

>>> '-3.14'.zfill(7) '-003.14'

>>> '3.14159265359'.zfill(5)
'3.14159265359'

7.1.4 Formatação de string antiga

O operador % (módulo) também pode ser usado para formatação de strings. Dados % valores de 'string', instâncias de % em string são substituídas
por zero ou mais elementos de valores. Esta operação é comumente conhecida como interpolação de strings.
Por exemplo:

>>> import math >>>


print('O valor de pi é aproximadamente %5.3f.' % math.pi)
O valor de pi é aproximadamente 3,142.

Mais informações podem ser encontradas na seção de formatação de strings antigas.

7.2 Lendo e Gravando Arquivos

open() retorna um objeto de arquivo e é mais comumente usado com dois argumentos posicionais e um argumento de palavra-chave: open(filename,
mode, encoding=None)

>>> f = open('arquivo de trabalho', 'w', encoding="utf-8")

O primeiro argumento é uma string contendo o nome do arquivo. O segundo argumento é outra string contendo alguns caracteres que descrevem a
maneira como o arquivo será usado. o modo pode ser 'r' quando o arquivo será apenas lido, 'w' apenas para gravação (um arquivo existente com o
mesmo nome será apagado) e 'a' abre o arquivo para anexação; quaisquer dados gravados no arquivo são adicionados automaticamente ao final. 'r+'
abre o arquivo para leitura e escrita. O argumento mode é opcional; 'r' será assumido se for omitido.

Normalmente, os arquivos são abertos em modo texto, ou seja, você lê e escreve strings de e para o arquivo, que são codificadas em uma codificação
específica. Se a codificação não for especificada, o padrão dependerá da plataforma (consulte open()). Como o UTF-8 é o padrão de fato moderno, a
codificação="utf-8" é recomendada, a menos que você saiba que precisa usar uma codificação diferente. Acrescentar um 'b' ao modo abre o arquivo no
modo binário. Os dados do modo binário são lidos e gravados como objetos de bytes. Você não pode especificar a codificação ao abrir o arquivo no
modo binário.

No modo de texto, o padrão durante a leitura é converter as terminações de linha específicas da plataforma (\n no Unix, \r\n no Windows) para apenas
\n. Ao escrever no modo de texto, o padrão é converter as ocorrências de \n de volta para finais de linha específicos da plataforma.
Essa modificação nos bastidores dos dados do arquivo é adequada para arquivos de texto, mas corromperá dados binários como os de arquivos JPEG
ou EXE. Tenha muito cuidado ao usar o modo binário ao ler e gravar esses arquivos.

É uma boa prática usar a palavra-chave with ao lidar com objetos de arquivo. A vantagem é que o arquivo é devidamente fechado após o término de
sua suíte, mesmo que uma exceção seja levantada em algum momento. Usar with também é muito mais curto do que escrever blocos try-finally
equivalentes:

>>> com open('workfile', encoding="utf-8") como f:


... read_data = f.read()

>>> # Podemos verificar se o arquivo foi fechado automaticamente. >>> f. fechado

Verdadeiro

7.2. Lendo e gravando arquivos 63


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Se você não estiver usando a palavra-chave with, deverá chamar f.close() para fechar o arquivo e liberar imediatamente quaisquer recursos do
sistema usados por ele.

Aviso: Chamar f.write() sem usar a palavra-chave with ou chamar f.close() pode fazer com que os argumentos de f.write() não sejam
completamente gravados no disco, mesmo se o programa for encerrado com êxito.

Depois que um objeto de arquivo é fechado, seja por uma instrução with ou chamando f.close(), as tentativas de usar o objeto de arquivo falharão
automaticamente.

>>> f.close() >>>


f.read()
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module> ValueError:
Operação de E/S em arquivo fechado.

7.2.1 Métodos de Objetos de Arquivo

O restante dos exemplos nesta seção assumirá que um objeto de arquivo chamado f já foi criado.

Para ler o conteúdo de um arquivo, chame f.read(size), que lê uma certa quantidade de dados e os retorna como uma string (em modo texto) ou
objeto de bytes (em modo binário). tamanho é um argumento numérico opcional. Quando o tamanho for omitido ou negativo, todo o conteúdo do
arquivo será lido e retornado; o problema é seu se o arquivo for duas vezes maior que a memória de sua máquina.
Caso contrário, no máximo caracteres de tamanho (no modo de texto) ou bytes de tamanho (no modo binário) são lidos e retornados. Se o final
do arquivo for atingido, f.read() retornará uma string vazia ('').

>>> f.read()
'Este é o arquivo inteiro.\n' >>> f.read()

''

f.readline() lê uma única linha do arquivo; um caractere de nova linha (\n) é deixado no final da string e só é omitido na última linha do arquivo se
o arquivo não terminar em uma nova linha. Isso torna o valor de retorno inequívoco; se f. readline() retorna uma string vazia, o final do arquivo
foi atingido, enquanto uma linha em branco é representada por '\n', uma string contendo apenas uma nova linha.

>>> f.readline()
'Esta é a primeira linha do arquivo.\n' >>> f.readline()

'Segunda linha do arquivo\n' >>> f.readline()

''

Para ler linhas de um arquivo, você pode fazer um loop sobre o objeto de arquivo. Isso é memória eficiente, rápido e leva a um código simples:

>>> para linha em f:


... print(linha, fim='')
...
Esta é a primeira linha do arquivo.
Segunda linha do arquivo

Se você quiser ler todas as linhas de um arquivo em uma lista, você também pode usar list(f) ou f.readlines().

f.write(string) escreve o conteúdo da string no arquivo, retornando o número de caracteres escritos.

64 Capítulo 7. Entrada e Saída


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> f.write('Isto é um teste\n') 15

Outros tipos de objetos precisam ser convertidos – em uma string (em modo de texto) ou em um objeto de bytes (em modo binário) – antes
de escrevê-los:

>>> valor = ('a resposta', 42) >>> s = str(valor) #


converte a tupla em string >>> f.write(s) 18

f.tell() retorna um inteiro dando a posição atual do objeto de arquivo no arquivo representado como número de bytes desde o início do
arquivo quando em modo binário e um número opaco quando em modo de texto.

Para alterar a posição do objeto de arquivo, use f.seek(offset, wherece). A posição é calculada adicionando deslocamento a um ponto de
referência; o ponto de referência é selecionado pelo argumento where . Um valor de onde 0 mede a partir do início do arquivo, 1 usa a
posição atual do arquivo e 2 usa o final do arquivo como ponto de referência. where pode ser omitido e o padrão é 0, usando o início do
arquivo como ponto de referência.

>>> f = open('workfile', 'rb+') >>>


f.write(b'0123456789abcdef')
16
>>> f.seek(5) # Vai para o 6º byte no arquivo
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # Vá para o 3º byte antes do final 13

>>> f.read(1) b'd'

Em arquivos de texto (aqueles abertos sem ab na string de modo), apenas buscas relativas ao início do arquivo são permitidas (a exceção
é buscar o final do arquivo com seek(0, 2)) e os únicos valores de deslocamento válidos são aqueles retornados de f.tell(), ou zero. Qualquer
outro valor de deslocamento produz um comportamento indefinido.

Os objetos de arquivo possuem alguns métodos adicionais, como isatty() e truncate(), que são usados com menos frequência; consulte o
Library Reference para obter um guia completo para arquivar objetos.

7.2.2 Salvando dados estruturados com json

Strings podem ser facilmente gravadas e lidas de um arquivo. Números exigem um pouco mais de esforço, já que o método read() retorna
apenas strings, que terão que ser passadas para uma função como int(), que pega uma string como '123' e retorna seu valor numérico 123.
Quando você quiser salvar tipos de dados mais complexos, como listas aninhadas e dicionários, analisar e serializar manualmente torna-se
complicado.

Em vez de ter usuários constantemente escrevendo e depurando código para salvar tipos de dados complicados em arquivos, o Python
permite que você use o popular formato de intercâmbio de dados chamado JSON (JavaScript Object Notation). O módulo padrão chamado
json pode pegar hierarquias de dados do Python e convertê-las em representações de string; esse processo é chamado de serialização.
A reconstrução dos dados da representação de string é chamada de desserialização. Entre a serialização e a desserialização, a string que
representa o objeto pode ter sido armazenada em um arquivo ou dados ou enviada por uma conexão de rede para alguma máquina distante.

Observação: o formato JSON é comumente usado por aplicativos modernos para permitir a troca de dados. Muitos programadores já estão
familiarizados com ele, o que o torna uma boa escolha para interoperabilidade.

7.2. Lendo e gravando arquivos 65


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Se você tiver um objeto x, poderá visualizar sua representação de string JSON com uma simples linha de código:

>>> import json >>>


x = [1, 'simples', 'lista'] >>> json.dumps(x)
'[1, "simples", "lista"]'

Outra variante da função dumps(), chamada dump(), simplesmente serializa o objeto em um arquivo de texto. Portanto, se f for um objeto de arquivo
de texto aberto para gravação, podemos fazer isso:

json.dump(x, f)

Para decodificar o objeto novamente, se f for um arquivo binário ou objeto de arquivo de texto que foi aberto para leitura:

x = json.load(f)

Observação: os arquivos JSON devem ser codificados em UTF-8. Use encoding="utf-8" ao abrir o arquivo JSON como um arquivo de texto para
leitura e gravação.

Essa técnica de serialização simples pode lidar com listas e dicionários, mas serializar instâncias de classes arbitrárias em JSON requer um pouco
de esforço extra. A referência para o módulo json contém uma explicação sobre isso.

Veja também:

pickle - o módulo pickle

Ao contrário do JSON, pickle é um protocolo que permite a serialização de objetos Python arbitrariamente complexos. Como tal, é específico para
Python e não pode ser usado para se comunicar com aplicativos escritos em outras linguagens. Também é inseguro por padrão: a desserialização
de dados pickle vindos de uma fonte não confiável pode executar código arbitrário, se os dados foram elaborados por um invasor habilidoso.

66 Capítulo 7. Entrada e Saída


Machine Translated by Google

CAPÍTULO

OITO

ERROS E EXCEÇÕES

Até agora, as mensagens de erro não foram mais do que mencionadas, mas se você experimentou os exemplos, provavelmente já viu alguns.
Existem (pelo menos) dois tipos distinguíveis de erros: erros de sintaxe e exceções.

8.1 Erros de sintaxe

Erros de sintaxe, também conhecidos como erros de análise, são talvez o tipo de reclamação mais comum que você recebe enquanto ainda está
aprendendo Python:

>>> while True print('Olá mundo')


Arquivo "<stdin>", linha 1
while True print('Olá mundo')
^

SyntaxError: sintaxe inválida

O analisador repete a linha problemática e exibe uma pequena 'seta' apontando para o primeiro ponto da linha onde o erro foi detectado. O erro é
causado (ou pelo menos detectado no) token que precede a seta: no exemplo, o erro é detectado na função print(), pois faltam dois pontos (':')
antes dela. O nome do arquivo e o número da linha são impressos para que você saiba onde procurar caso a entrada venha de um script.

8.2 Exceções
Mesmo que uma instrução ou expressão esteja sintaticamente correta, ela pode causar um erro ao tentar executá-la.
Erros detectados durante a execução são chamados de exceções e não são incondicionalmente fatais: em breve você aprenderá como tratá-los
em programas Python. A maioria das exceções não são tratadas por programas, no entanto, e resultam em mensagens de erro, conforme
mostrado aqui:

>>> 10 * (1/0)
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
ZeroDivisionError: divisão por zero >>> 4 + spam*3

Traceback (última chamada mais recente):


Arquivo "<stdin>", linha 1, em <module>
NameError: o nome 'spam' não está definido >>> '2' + 2

Traceback (última chamada mais recente):


Arquivo "<stdin>", linha 1, em <module>
TypeError: só pode concatenar str (não "int") para str

67
Machine Translated by Google

Tutorial do Python, versão 3.11.3

A última linha da mensagem de erro indica o que aconteceu. Exceções vêm em tipos diferentes, e o tipo é impresso como parte da mensagem: os tipos
no exemplo são ZeroDivisionError, NameError e TypeError. A string impressa como o tipo de exceção é o nome da exceção interna que ocorreu. Isso é
verdadeiro para todas as exceções internas, mas não precisa ser verdadeiro para exceções definidas pelo usuário (embora seja uma convenção útil).
Os nomes de exceção padrão são identificadores integrados (não palavras-chave reservadas).

O restante da linha fornece detalhes com base no tipo de exceção e no que a causou.

A parte anterior da mensagem de erro mostra o contexto em que ocorreu a exceção, na forma de um rastreamento de pilha.
Em geral, ele contém um rastreamento de pilha listando as linhas de origem; no entanto, ele não exibirá as linhas lidas da entrada padrão.

bltin-exceptions lista as exceções internas e seus significados.

8.3 Manipulando Exceções

É possível escrever programas que lidam com exceções selecionadas. Observe o exemplo a seguir, que solicita entrada do usuário até que um inteiro
válido seja inserido, mas permite que o usuário interrompa o programa (usando Control-C ou qualquer outro suporte do sistema operacional); observe
que uma interrupção gerada pelo usuário é sinalizada levantando a exceção KeyboardInterrupt.

>>> enquanto Verdadeiro:


... try: x
... = int(input(" Digite um número: ")) break
...
... except ValueError:
... print("Oops! Esse número não é válido. Tente novamente...")
...

A instrução try funciona da seguinte maneira.

• Primeiro, a cláusula try (a(s) instrução(ões) entre as palavras-chave try e except) é executada.

• Se não ocorrer nenhuma exceção, a cláusula except é ignorada e a execução da instrução try é encerrada.

• Se ocorrer uma exceção durante a execução da cláusula try, o restante da cláusula será ignorado. Então, se seu tipo corresponder à exceção
nomeada após a palavra-chave except, a cláusula except é executada e a execução continua após o bloco try/except.

• Se ocorrer uma exceção que não corresponda à exceção nomeada na cláusula except, ela será passada para as instruções try externas; se
nenhum manipulador for encontrado, será uma exceção não tratada e a execução será interrompida com uma mensagem conforme mostrado acima.

Uma instrução try pode ter mais de uma cláusula except, para especificar manipuladores para diferentes exceções. No máximo um manipulador será
executado. Os manipuladores lidam apenas com exceções que ocorrem na cláusula try correspondente, não em outros manipuladores da mesma
instrução try. Uma cláusula except pode nomear várias exceções como uma tupla entre parênteses, por exemplo:

... exceto (RuntimeError, TypeError, NameError):


... passar

Uma classe em uma cláusula except é compatível com uma exceção se for a mesma classe ou uma classe base dela (mas não o contrário — uma
cláusula except listando uma classe derivada não é compatível com uma classe base). Por exemplo, o código a seguir imprimirá B, C, D nessa ordem:

classe B(Exceção):
passar

classe C(B):
passar
(continua na próxima página)

68 Capítulo 8. Erros e Exceções


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

classe D(C):
passar

para cls em [B, C, D]: tente:


raise
cls() exceto D:
print("D")
exceto C:
print("C")
exceto B:
print("B")

Observe que se as cláusulas except fossem invertidas (com except B primeiro), teria impresso B, B, B — a primeira cláusula except
correspondente é acionada.

Quando ocorre uma exceção, ela pode ter valores associados, também conhecidos como argumentos da exceção . A presença e os tipos dos
argumentos dependem do tipo de exceção.

A cláusula except pode especificar uma variável após o nome da exceção. A variável está vinculada à instância de exceção que normalmente
possui um atributo args que armazena os argumentos. Por conveniência, os tipos de exceção internos definem __str__() para imprimir todos
os argumentos sem acessar .args explicitamente.

>>> tente:
... raise Exception('spam', 'eggs')
... exceto Exceção como inst:
... print(type(inst)) # o tipo de exceção #
... print(inst.args) print(inst) argumentos armazenados em .args #
... __str__ permite que args sejam impressos diretamente, # mas pode
... ser substituído em subclasses de exceção # unpack args
... x, y = inst.args print('x =',
... x) print('y =', y)
...
...
<class 'Exception'> ('spam',
'eggs') ('spam', 'eggs')

x = spam
y = ovos

A saída __str__() da exceção é impressa como a última parte ('detalhe') da mensagem para exceções não tratadas.

BaseException é a classe base comum de todas as exceções. Uma de suas subclasses, Exception, é a classe base de todas as exceções não
fatais. Exceções que não são subclasses de Exception normalmente não são tratadas, porque são usadas para indicar que o programa deve
terminar. Eles incluem SystemExit, que é gerado por sys.exit() e KeyboardInterrupt, que é gerado quando um usuário deseja interromper o
programa.

A exceção pode ser usada como um curinga que captura (quase) tudo. No entanto, é uma boa prática ser o mais específico possível com os
tipos de exceções que pretendemos tratar e permitir que quaisquer exceções inesperadas se propaguem.

O padrão mais comum para lidar com Exception é imprimir ou registrar a exceção e, em seguida, aumentá-la novamente (permitindo que um
chamador manipule a exceção também):

sistema de importação

tentar:
(continua na próxima página)

8.3. Manipulando Exceções 69


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

f = open('myfile.txt') s = f.readline()
i = int(s.strip()) exceto
OSError como err:

print(" Erro do sistema operacional:",


err) exceto ValueError:
print("Não foi possível converter dados em um número inteiro.")
except Exception as err:
print(f"Inesperado {err=}, {type(err)=}")
elevação

A instrução try … except tem uma cláusula else opcional que, quando presente, deve seguir todas as cláusulas exceto. É útil para o
código que deve ser executado se a cláusula try não gerar uma exceção. Por exemplo:

for arg in sys.argv[1:]: try: f = open(arg,


'r')
exceto OSError: print('cannot
open', arg)

outro:
print(arg, 'tem', len(f.readlines()), 'linhas') f.close()

O uso da cláusula else é melhor do que adicionar código adicional à cláusula try porque evita capturar acidentalmente uma exceção
que não foi gerada pelo código protegido pela instrução try … except.

Os manipuladores de exceção não lidam apenas com as exceções que ocorrem imediatamente na cláusula try, mas também com aquelas que ocorrem
dentro das funções que são chamadas (mesmo que indiretamente) na cláusula try. Por exemplo:

>>> def this_fails(): x = 1/0


...
...
>>> tente:
... this_fails()
... exceto ZeroDivisionError como err: print('Manipulando
... erro de tempo de execução:', err)
...
Tratamento de erro em tempo de execução: divisão por zero

8.4 Gerando Exceções

A instrução raise permite ao programador forçar a ocorrência de uma exceção especificada. Por exemplo:

>>> raise NameError('HiThere')


Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
NameError: HiThere

O único argumento para levantar indica a exceção a ser levantada. Deve ser uma instância de exceção ou uma classe de exceção
(uma classe derivada de BaseException, como Exception ou uma de suas subclasses). Se uma classe de exceção for passada, ela
será instanciada implicitamente chamando seu construtor sem argumentos:

raise ValueError # abreviação de 'raise ValueError()'

70 Capítulo 8. Erros e Exceções


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Se você precisa determinar se uma exceção foi lançada, mas não pretende tratá-la, uma forma mais simples da instrução raise
permite que você gere novamente a exceção:

>>> tente:
... raise NameError('HiThere') ... exceto
NameError: print('Uma exceção
... passou voando!') raise
...
...
Uma exceção passou voando!
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 2, em <module>
NameError: HiThere

8.5 Encadeamento de Exceções

Se uma exceção não tratada ocorrer dentro de uma seção exceto, ela terá a exceção sendo tratada anexada a ela e incluída na
mensagem de erro:

>>> tente:
... open("database.sqlite") ... exceto
OSError: raise
... RuntimeError("não foi possível manipular o erro")
...
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 2, em <module> FileNotFoundError:
[Errno 2] Arquivo ou diretório inexistente: 'database.sqlite'

Durante o tratamento da exceção acima, outra exceção ocorreu:

Traceback (última chamada mais recente):


Arquivo "<stdin>", linha 4, em <module>
RuntimeError: incapaz de lidar com o erro

Para indicar que uma exceção é consequência direta de outra, a instrução raise permite uma cláusula from opcional:

# exc deve ser instância de exceção ou None. aumentar


RuntimeError de exc

Isso pode ser útil quando você está transformando exceções. Por exemplo:

>>> função def ():


... aumentar ConnectionError
...
>>> tente:
... func()
... exceto ConnectionError as exc: raise
... RuntimeError('Failed to open database') from exc
...
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 2, em <module>
Arquivo "<stdin>", linha 2, em func
Erro de conexão

A exceção acima foi a causa direta da seguinte exceção:


(continua na próxima página)

8.5. Encadeamento de exceção 71


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

Traceback (última chamada mais recente):


Arquivo "<stdin>", linha 4, em <module>
RuntimeError: Falha ao abrir o banco de dados

Ele também permite desabilitar o encadeamento automático de exceções usando o idioma from None:

>>> tente:
... open('database.sqlite') ... exceto
OSError:
... elevar RuntimeError de None
...
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 4, em <module>
RuntimeError

Para obter mais informações sobre a mecânica de encadeamento, consulte bltin-exceptions.

8.6 Exceções definidas pelo usuário

Os programas podem nomear suas próprias exceções criando uma nova classe de exceção (consulte Classes para saber mais sobre as classes do Python).
As exceções geralmente devem ser derivadas da classe Exception, direta ou indiretamente.

Classes de exceção podem ser definidas para fazer qualquer coisa que qualquer outra classe pode fazer, mas geralmente são mantidas simples, muitas vezes
oferecendo apenas um número de atributos que permitem que informações sobre o erro sejam extraídas por manipuladores para a exceção.

A maioria das exceções são definidas com nomes que terminam em “Error”, semelhante à nomenclatura das exceções padrão.

Muitos módulos padrão definem suas próprias exceções para relatar erros que podem ocorrer nas funções que eles definem.

8.7 Definindo ações de limpeza

A instrução try tem outra cláusula opcional que se destina a definir ações de limpeza que devem ser executadas em todas as circunstâncias. Por
exemplo:

>>> tente:
... aumentar a interrupção do teclado
... finalmente:
... print('Adeus, mundo!')
...
Adeus mundo!
KeyboardInterrupt
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 2, em <module>

Se uma cláusula finalmente estiver presente, ela será executada como a última tarefa antes da conclusão da instrução try.
A cláusula final é executada quer a instrução try produza ou não uma exceção. Os pontos a seguir discutem casos mais complexos quando ocorre
uma exceção:

• Se ocorrer uma exceção durante a execução da cláusula try, a exceção pode ser tratada por uma cláusula except. Se a exceção não for
tratada por uma cláusula except, a exceção é levantada novamente após a execução da cláusula final.

72 Capítulo 8. Erros e Exceções


Machine Translated by Google

Tutorial do Python, versão 3.11.3

• Uma exceção pode ocorrer durante a execução de uma cláusula except ou else. Novamente, a exceção é gerada novamente após
a cláusula final foi executada.

• Se a cláusula finalmente executa uma instrução break, continue ou return, as exceções não são geradas novamente.

• Se a instrução try atingir uma instrução break, continue ou return, a cláusula final será executada apenas
antes do intervalo, continue ou retorne a execução da instrução.

• Se uma cláusula final incluir uma instrução return, o valor retornado será aquele da cláusula final
instrução return, não o valor da instrução return da cláusula try.

Por exemplo:

>>> def bool_return(): tente:


...
... retornar Verdadeiro
...
... finalmente: retornar Falso
...
>>> bool_return()
Falso

Um exemplo mais complicado:

>>> def divide(x, y): tente:


...
... resultado = x / y exceto
... ZeroDivisionError:
... print("divisão por zero!")
... outro:
... print("resultado é", resultado)
... finalmente:
... print("executando cláusula final")
...
>>> divide(2, 1) o
resultado é 2,0
executando a cláusula final >>>
divide(2, 0) divisão por
zero! executando a
cláusula final >>> divide("2", "1")
executando a cláusula final
Traceback (última chamada mais
recente):
Arquivo "<stdin>", linha 1, em <module>
Arquivo "<stdin>", linha 3, em divisão
TypeError: tipo(s) de operando não suportado para /: 'str' e 'str'

Como você pode ver, a cláusula final é executada em qualquer evento. O TypeError gerado pela divisão de duas strings não é manipulado
pela cláusula except e, portanto, gerado novamente após a execução da cláusula final.

Em aplicações do mundo real, a cláusula final é útil para liberar recursos externos (como arquivos ou conexões de rede),
independentemente de o uso do recurso ter sido bem-sucedido.

8.7. Definindo ações de limpeza 73


Machine Translated by Google

Tutorial do Python, versão 3.11.3

8.8 Ações de limpeza predefinidas

Alguns objetos definem ações de limpeza padrão a serem executadas quando o objeto não é mais necessário, independentemente de a operação
que usa o objeto ter sido bem-sucedida ou não. Veja o exemplo a seguir, que tenta abrir um arquivo e imprimir seu conteúdo na tela.

for line in open("myfile.txt"): print(line, end="")

O problema com esse código é que ele deixa o arquivo aberto por tempo indeterminado após o término da execução dessa parte do código. Isso
não é um problema em scripts simples, mas pode ser um problema para aplicativos maiores. A instrução with permite que objetos como arquivos
sejam usados de forma a garantir que sejam sempre limpos de forma rápida e correta.

with open("myfile.txt") as f: for line in f:

print(linha, fim="")

Depois que a instrução é executada, o arquivo f é sempre fechado, mesmo que seja encontrado um problema durante o processamento das linhas.
Objetos que, como arquivos, fornecem ações de limpeza predefinidas indicarão isso em sua documentação.

8.9 Levantamento e Tratamento de Múltiplas Exceções Não Relacionadas

Existem situações em que é necessário relatar várias exceções ocorridas. Esse é frequentemente o caso em estruturas de simultaneidade, quando
várias tarefas podem ter falhado em paralelo, mas também há outros casos de uso em que é desejável continuar a execução e coletar vários erros
em vez de gerar a primeira exceção.

O ExceptionGroup interno agrupa uma lista de instâncias de exceção para que possam ser geradas juntas. É uma exceção em si, portanto pode
ser capturada como qualquer outra exceção.

>>> def f():


... excs = [OSError('erro 1'), SystemError('erro 2')] raise ExceptionGroup(' houve
... problemas', excs)
...
>>> f()
+ Exception Group Traceback (última chamada mais recente):
| Arquivo "<stdin>", linha 1, em <module>
| Arquivo "<stdin>", linha 3, em f
| ExceptionGroup: houve problemas +-+---------------- 1
----------------
| OSError: erro 1 +----------------
2 ----------------
| SystemError: erro 2
+-----------------------------------
>>> tente:
... f()
... exceto Exceção como e:
... print(f'pegou {type(e)}: e')
...
capturado <class 'ExceptionGroup'>: e
>>>

Usando except* em vez de except, podemos manipular seletivamente apenas as exceções no grupo que correspondem a um determinado tipo. No
exemplo a seguir, que mostra um grupo de exceções aninhadas, cada cláusula except* extrai do grupo exceções de um determinado tipo,
permitindo que todas as outras exceções se propaguem para outras cláusulas e, eventualmente, sejam levantadas novamente.

74 Capítulo 8. Erros e Exceções


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> def f(): raise


... ExceptionGroup("grupo1",
... [OSError(1),
... SystemError(2),
... ExceptionGroup("grupo2",
... [OSError(3), RecursionError(4)])])
...
>>> tente:
... f()
... exceto* OSError como e:
... print("Havia OSErrors") ... except*
SystemError as e: print("Havia SystemErrors")
...
...
Ocorreram erros de OSE
Ocorreram erros do sistema
+ Exception Group Traceback (última chamada mais recente):
| Arquivo "<stdin>", linha 2, em <module>
| Arquivo "<stdin>", linha 2, em f
| ExceptionGroup: group1 +-
+---------------- 1 ----------------
| ExceptionGroup: group2 +-
+---------------- 1 ----------------
| Erro de recursão: 4
+-----------------------------------
>>>

Observe que as exceções aninhadas em um grupo de exceção devem ser instâncias, não tipos. Isso ocorre porque, na prática,
as exceções normalmente seriam aquelas que já foram levantadas e capturadas pelo programa, seguindo o seguinte padrão:

>>> excs = [] ... para


teste em testes:
... tente:
... test.run()
... exceto Exceção como e:
... excs.append(e)
...
>>> se excs:
... raise ExceptionGroup("Test Failures", excs)
...

8.10 Enriquecendo Exceções com Notas

Quando uma exceção é criada para ser levantada, geralmente ela é inicializada com informações que descrevem o erro
ocorrido. Existem casos em que é útil adicionar informações após a captura da exceção. Para isso, as exceções possuem um
método add_note(note) que aceita uma string e a adiciona à lista de notas da exceção. A renderização padrão do traceback
inclui todas as notas, na ordem em que foram adicionadas, após a exceção.

>>> tente:
... raise TypeError(' tipo ruim')
... exceto Exceção como e:
... e.add_note('Adicione algumas informações')
... e.add_note('Adicione mais algumas informações') raise
...
(continua na próxima página)

8.10. Enriquecendo exceções com notas 75


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

...
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 2, em <module>
TypeError: tipo ruim
Adicione algumas informações
Adicione mais algumas informações
>>>

Por exemplo, ao coletar exceções em um grupo de exceção, podemos adicionar informações de contexto para os
erros individuais. A seguir, cada exceção no grupo possui uma nota indicando quando esse erro ocorreu.

>>> def f(): raise


... OSError('operação falhou')
...
>>> excs = [] >>>
for i in range(3): try: f() except
...
... Exception
... as e:
... e.add_note(f'Ocorreu na iteração {i+1}') excs.append(e)
...
...
>>> raise ExceptionGroup('Temos alguns problemas', excs)
+ Exception Group Traceback (última chamada mais recente):
| Arquivo "<stdin>", linha 1, em <module>
| ExceptionGroup: Temos alguns problemas (3 sub-exceções)
+-+---------------- 1 ----------------
| Traceback (última chamada mais recente):
| Arquivo "<stdin>", linha 3, em <module>
| Arquivo "<stdin>", linha 2, em f
| OSError: falha na operação
| Aconteceu na Iteração 1
+---------------- 2 ----------------
| Traceback (última chamada mais recente):
| Arquivo "<stdin>", linha 3, em <module>
| Arquivo "<stdin>", linha 2, em f
| OSError: falha na operação
| Aconteceu na iteração 2 +----------------
3 ----------------
| Traceback (última chamada mais recente):
| Arquivo "<stdin>", linha 3, em <module>
| Arquivo "<stdin>", linha 2, em f
| OSError: falha na operação
| Aconteceu na Iteração 3
+-----------------------------------
>>>

76 Capítulo 8. Erros e Exceções


Machine Translated by Google

CAPÍTULO

NOVE

AULAS

As classes fornecem um meio de agrupar dados e funcionalidades. A criação de uma nova classe cria um novo tipo de objeto, permitindo que novas
instâncias desse tipo sejam feitas. Cada instância de classe pode ter atributos anexados a ela para manter seu estado. As instâncias de classe também
podem ter métodos (definidos por sua classe) para modificar seu estado.

Comparado com outras linguagens de programação, o mecanismo de classe do Python adiciona classes com um mínimo de nova sintaxe e semântica.
É uma mistura dos mecanismos de classe encontrados em C++ e Modula-3. As classes Python fornecem todos os recursos padrão da Programação
Orientada a Objetos: o mecanismo de herança de classe permite várias classes base, uma classe derivada pode substituir quaisquer métodos de sua
classe ou classes base e um método pode chamar o método de uma classe base com o mesmo nome . Os objetos podem conter quantidades e tipos
de dados arbitrários. Como acontece com os módulos, as classes participam da natureza dinâmica do Python: elas são criadas em tempo de execução
e podem ser modificadas posteriormente após a criação.

Na terminologia C++, normalmente os membros de classe (incluindo os membros de dados) são públicos (exceto veja abaixo as Variáveis Privadas) e
todas as funções de membro são virtuais. Como no Modula-3, não há atalhos para referenciar os membros do objeto a partir de seus métodos: a
função do método é declarada com um primeiro argumento explícito representando o objeto, que é fornecido implicitamente pela chamada. Como em
Smalltalk, as próprias classes são objetos. Isso fornece semântica para importar e renomear.
Ao contrário de C++ e Modula-3, os tipos internos podem ser usados como classes base para extensão pelo usuário. Além disso, como em C++, a
maioria dos operadores integrados com sintaxe especial (operadores aritméticos, subscritos, etc.) podem ser redefinidos para instâncias de classe.

(Na falta de terminologia universalmente aceita para falar sobre classes, farei uso ocasional de termos Smalltalk e C++.
Eu usaria os termos do Modula-3, já que sua semântica orientada a objetos é mais próxima da do Python do que do C++, mas espero que poucos
leitores tenham ouvido falar dele.)

9.1 Uma palavra sobre nomes e objetos

Os objetos têm individualidade e vários nomes (em vários escopos) podem ser vinculados ao mesmo objeto. Isso é conhecido como aliasing em outros
idiomas. Isso geralmente não é apreciado à primeira vista no Python e pode ser ignorado com segurança ao lidar com tipos básicos imutáveis (números,
strings, tuplas). No entanto, o aliasing tem um efeito possivelmente surpreendente na semântica do código Python envolvendo objetos mutáveis, como
listas, dicionários e a maioria dos outros tipos. Isso geralmente é usado em benefício do programa, pois os aliases se comportam como ponteiros em
alguns aspectos. Por exemplo, passar um objeto é barato, pois apenas um ponteiro é passado pela implementação; e se uma função modificar um
objeto passado como um argumento, o chamador verá a mudança — isso elimina a necessidade de dois mecanismos diferentes de passagem de
argumentos como em Pascal.

77
Machine Translated by Google

Tutorial do Python, versão 3.11.3

9.2 Escopos e Namespaces do Python

Antes de apresentar as classes, primeiro preciso dizer algo sobre as regras de escopo do Python. As definições de classe executam alguns truques
legais com namespaces, e você precisa saber como escopos e namespaces funcionam para entender completamente o que está acontecendo.
Aliás, o conhecimento sobre esse assunto é útil para qualquer programador Python avançado.

Vamos começar com algumas definições.

Um namespace é um mapeamento de nomes para objetos. A maioria dos namespaces são atualmente implementados como dicionários do Python,
mas isso normalmente não é perceptível de forma alguma (exceto pelo desempenho) e pode mudar no futuro. Exemplos de namespaces são: o
conjunto de nomes integrados (contendo funções como abs() e nomes de exceção integrados); os nomes globais em um módulo; e os nomes locais
em uma chamada de função. Em certo sentido, o conjunto de atributos de um objeto também forma um namespace. O importante a saber sobre
namespaces é que não há absolutamente nenhuma relação entre nomes em diferentes namespaces; por exemplo, dois módulos diferentes podem
definir uma função maximizar sem confusão — os usuários dos módulos devem prefixá-lo com o nome do módulo.

A propósito, eu uso a palavra atributo para qualquer nome após um ponto — por exemplo, na expressão z.real, real é um atributo do objeto z.
Estritamente falando, referências a nomes em módulos são referências a atributos: na expressão modname.funcname, modname é um objeto módulo
e funcname é um atributo dele. Nesse caso, ocorre um mapeamento direto entre os atributos do módulo e os nomes globais definidos no módulo:
eles compartilham o mesmo namespace!1

Os atributos podem ser somente leitura ou graváveis. No último caso, a atribuição de atributos é possível. Os atributos do módulo são graváveis:
você pode escrever modname.the_answer = 42. Os atributos graváveis também podem ser excluídos com a instrução del. Por exemplo, del
modname.the_answer removerá o atributo the_answer do objeto nomeado por modname.

Os namespaces são criados em momentos diferentes e têm tempos de vida diferentes. O namespace que contém os nomes integrados é criado
quando o interpretador Python é inicializado e nunca é excluído. O namespace global para um módulo é criado quando a definição do módulo é lida;
normalmente, os namespaces do módulo também duram até que o interpretador saia. As instruções executadas pela chamada de nível superior do
interpretador, sejam lidas de um arquivo de script ou interativamente, são consideradas parte de um módulo chamado __main__, portanto, possuem
seu próprio namespace global. (Na verdade, os nomes integrados também residem em um módulo; isso é chamado de builtins.)

O namespace local para uma função é criado quando a função é chamada e excluído quando a função retorna ou gera uma exceção que não é
tratada dentro da função. (Na verdade, esquecer seria uma maneira melhor de descrever o que realmente acontece.) É claro que cada uma das
invocações recursivas tem seu próprio namespace local.

Um escopo é uma região textual de um programa Python onde um namespace é diretamente acessível. “Acessível diretamente” aqui significa que
uma referência não qualificada a um nome tenta localizar o nome no namespace.

Embora os escopos sejam determinados estaticamente, eles são usados dinamicamente. A qualquer momento durante a execução, existem 3 ou 4
escopos aninhados cujos namespaces são diretamente acessíveis:

• o escopo mais interno, que é pesquisado primeiro, contém os nomes locais

• os escopos de quaisquer funções de inclusão, que são pesquisadas começando com o escopo de inclusão mais próximo, não contêm
nomes locais, mas também não globais

• o penúltimo escopo contém os nomes globais do módulo atual

• o escopo mais externo (pesquisado por último) é o namespace que contém nomes integrados

Se um nome for declarado global, todas as referências e atribuições vão diretamente para o penúltimo escopo que contém os nomes globais do
módulo. Para religar variáveis encontradas fora do escopo mais interno, a instrução nonlocal pode ser usada; se não forem declaradas não locais,
essas variáveis serão somente leitura (uma tentativa de gravar em tal variável simplesmente criará uma nova variável local no escopo mais interno,
deixando inalterada a variável externa com nome idêntico).

1 Exceto por uma coisa. Os objetos do módulo têm um atributo somente leitura secreto chamado __dict__ que retorna o dicionário usado para
implementar o namespace do módulo; o nome __dict__ é um atributo, mas não um nome global. Obviamente, usar isso viola a abstração da
implementação do namespace e deve ser restrito a coisas como depuradores post-mortem.

78 Capítulo 9. Aulas
Machine Translated by Google

Tutorial do Python, versão 3.11.3

Normalmente, o escopo local faz referência aos nomes locais da função atual (textualmente). Fora das funções, o escopo local faz
referência ao mesmo namespace do escopo global: o namespace do módulo. As definições de classe colocam ainda outro ritmo de
nomes no escopo local.

É importante perceber que os escopos são determinados textualmente: o escopo global de uma função definida em um módulo é o
namespace desse módulo, não importa de onde ou por qual alias a função é chamada. Por outro lado, a busca real por nomes é feita
dinamicamente, em tempo de execução — no entanto, a definição da linguagem está evoluindo para uma resolução estática de nomes,
em tempo de “compilação”, então não confie na resolução dinâmica de nomes! (Na verdade, as variáveis locais já são determinadas estaticamente.)

Uma peculiaridade especial do Python é que – se nenhuma instrução global ou não local estiver em vigor – as atribuições a nomes
sempre vão para o escopo mais interno. As atribuições não copiam dados — elas apenas vinculam nomes a objetos. O mesmo vale para
exclusões: a instrução del x remove a ligação de x do namespace referenciado pelo escopo local. Na verdade, todas as operações que
introduzem novos nomes usam o escopo local: em particular, instruções de importação e definições de função ligam o módulo ou o nome
da função no escopo local.

A instrução global pode ser usada para indicar que variáveis específicas residem no escopo global e devem ser religadas lá; a instrução
nonlocal indica que variáveis específicas residem em um escopo envolvente e devem ser religadas lá.

9.2.1 Exemplo de Escopos e Namespaces

Este é um exemplo que demonstra como fazer referência a diferentes escopos e namespaces e como global e não local afetam a
vinculação de variáveis:

def scope_test(): def


do_local(): spam =
"spam local"

def do_nonlocal(): spam


não local spam =
"spam não local"

def do_global(): spam


global spam =
"spam global"

spam = "teste de spam"


do_local()
print("Após atribuição local:", spam) do_nonlocal()

print("Após atribuição não local:", spam) do_global() print("Após


atribuição
global:", spam)

scope_test()
print("No escopo global:", spam)

A saída do código de exemplo é:

Após atribuição local: teste de spam


Após atribuição não local: spam não local
Após atribuição global: spam não local
No escopo global: spam global

Observe como a atribuição local (que é padrão) não alterou a ligação de spam do scope_test . A atribuição não local alterou a vinculação
de spam do scope_test e a atribuição global alterou a vinculação no nível do módulo.

Você também pode ver que não havia ligação anterior para spam antes da atribuição global.

9.2. Escopos e Namespaces do Python 79


Machine Translated by Google

Tutorial do Python, versão 3.11.3

9.3 Uma primeira olhada nas aulas

As classes introduzem um pouco da nova sintaxe, três novos tipos de objeto e algumas novas semânticas.

9.3.1 Sintaxe de Definição de Classe

A forma mais simples de definição de classe é assim:

class ClassName:
<declaração-1>
.
.
.
<declaração-N>

As definições de classe, como as definições de função (instruções def), devem ser executadas antes de terem qualquer efeito. (Você poderia
colocar uma definição de classe em uma ramificação de uma instrução if ou dentro de uma função.)

Na prática, as instruções dentro de uma definição de classe geralmente serão definições de função, mas outras instruções são permitidas
e, às vezes, úteis — voltaremos a isso mais tarde. As definições de função dentro de uma classe normalmente têm uma forma peculiar de
lista de argumentos, ditada pelas convenções de chamada de métodos — novamente, isso será explicado posteriormente.

Quando uma definição de classe é inserida, um novo namespace é criado e usado como escopo local — portanto, todas as atribuições a
variáveis locais vão para esse novo namespace. Em particular, as definições de função vinculam o nome da nova função aqui.

Quando uma definição de classe é deixada normalmente (pelo final), um objeto de classe é criado. Isso é basicamente um wrapper em
torno do conteúdo do namespace criado pela definição de classe; aprenderemos mais sobre objetos de classe na próxima seção. O escopo
local original (aquele em vigor imediatamente antes da entrada da definição de classe) é restabelecido e o objeto de classe é vinculado aqui
ao nome de classe fornecido no cabeçalho de definição de classe (ClassName no exemplo).

9.3.2 Objetos de Classe

Os objetos de classe suportam dois tipos de operações: referências de atributo e instanciação.

Referências de atributos usam a sintaxe padrão usada para todas as referências de atributos em Python: obj.name. Nomes de atributo
válidos são todos os nomes que estavam no namespace da classe quando o objeto de classe foi criado. Portanto, se a definição da classe
fosse assim:

classe MinhaClasse:
"""Uma classe de exemplo simples""" i = 12345

def f(self): return


'olá mundo'

então MyClass.i e MyClass.f são referências de atributo válidas, retornando um inteiro e um objeto de função, respectivamente.
Os atributos de classe também podem ser atribuídos, portanto, você pode alterar o valor de MyClass.i por atribuição. __doc__ também é
um atributo válido, retornando a docstring pertencente à classe: "A simple example class".

A instanciação de classe usa notação de função. Apenas finja que o objeto de classe é uma função sem parâmetros que retorna uma nova
instância da classe. Por exemplo (assumindo a classe acima):

x = MinhaClasse()

80 Capítulo 9. Aulas
Machine Translated by Google

Tutorial do Python, versão 3.11.3

cria uma nova instância da classe e atribui esse objeto à variável local x.

A operação de instanciação (“chamando” um objeto de classe) cria um objeto vazio. Muitas classes gostam de criar objetos com instâncias
personalizadas para um estado inicial específico. Portanto, uma classe pode definir um método especial chamado __init__(), assim:

def __init__(self):
self.data = []

Quando uma classe define um método __init__(), a instanciação de classe invoca automaticamente __init__() para a instância de classe recém-
criada. Portanto, neste exemplo, uma nova instância inicializada pode ser obtida por:

x = MinhaClasse()

Claro, o método __init__() pode ter argumentos para maior flexibilidade. Nesse caso, os argumentos fornecidos ao operador de instanciação de
classe são passados para __init__(). Por exemplo,

>>> classe Complex: def


... __init__(self, realpart, imagpart):
... self.r = parte real self.i =
... parte da imagem
...
>>> x = Complex(3.0, -4.5) >>> xr, xi (3.0,
-4.5)

9.3.3 Objetos de Instância

Agora, o que podemos fazer com objetos de instância? As únicas operações compreendidas pelos objetos de instância são referências de atributo.
Existem dois tipos de nomes de atributos válidos: atributos de dados e métodos.

atributos de dados correspondem a “variáveis de instância” em Smalltalk e a “membros de dados” em C++. Os atributos de dados não precisam
ser declarados; como variáveis locais, eles surgem quando são atribuídos pela primeira vez. Por exemplo, se x for a instância de MyClass criada
acima, o seguinte trecho de código imprimirá o valor 16, sem deixar vestígios:

x.contador = 1
enquanto x.counter < 10:
x.counter = x.counter * 2
print(x.counter) del
x.counter

O outro tipo de referência de atributo de instância é um método. Um método é uma função que “pertence a” um objeto. (Em Python, o termo
método não é exclusivo para instâncias de classe: outros tipos de objeto também podem ter métodos. Por exemplo, objetos de lista têm métodos
chamados append, insert, remove, sort e assim por diante. No entanto, na discussão a seguir, usaremos o termo método exclusivamente para
significar métodos de objetos de instância de classe, a menos que seja explicitamente declarado o contrário.)

Os nomes de métodos válidos de um objeto de instância dependem de sua classe. Por definição, todos os atributos de uma classe que são objetos
de função definem métodos correspondentes de suas instâncias. Portanto, em nosso exemplo, xf é uma referência de método válida, pois MyClass.f
é uma função, mas xi não é, pois MyClass.i não é. Mas xf não é a mesma coisa que MyClass.f — é um objeto de método, não um objeto de função.

9.3. Uma primeira olhada nas aulas 81


Machine Translated by Google

Tutorial do Python, versão 3.11.3

9.3.4 Objetos de Método


Normalmente, um método é chamado logo após ser vinculado:

xf()

No exemplo MyClass, isso retornará a string 'hello world'. No entanto, não é necessário chamar um método imediatamente: xf é um objeto de
método e pode ser armazenado e chamado posteriormente. Por exemplo:

xf = xf
enquanto verdadeiro:

imprimir(xf())

continuará a imprimir olá mundo até o fim dos tempos.

O que exatamente acontece quando um método é chamado? Você deve ter notado que xf() foi chamado sem um argumento acima, mesmo
que a definição da função para f() tenha especificado um argumento. O que aconteceu com o argumento? Certamente o Python gera uma
exceção quando uma função que requer um argumento é chamada sem nenhum — mesmo que o argumento não seja realmente usado…

Na verdade, você deve ter adivinhado a resposta: o que há de especial nos métodos é que o objeto de instância é passado como o primeiro
argumento da função. Em nosso exemplo, a chamada xf() é exatamente equivalente a MyClass.f(x). Em geral, chamar um método com uma
lista de n argumentos é equivalente a chamar a função correspondente com uma lista de argumentos que é criada inserindo o objeto de
instância do método antes do primeiro argumento.

Se você ainda não entende como os métodos funcionam, uma olhada na implementação talvez possa esclarecer as coisas. Quando um
atributo não de dados de uma instância é referenciado, a classe da instância é pesquisada. Se o nome denota um atributo de classe válido que
é um objeto de função, um objeto de método é criado empacotando (ponteiros para) o objeto de instância e o objeto de função que acabaram
de ser encontrados juntos em um objeto abstrato: este é o objeto de método. Quando o objeto de método é chamado com uma lista de
argumentos, uma nova lista de argumentos é construída a partir do objeto de instância e da lista de argumentos, e o objeto de função é
chamado com essa nova lista de argumentos.

9.3.5 Variáveis de Classe e Instância

De um modo geral, as variáveis de instância são para dados exclusivos de cada instância e as variáveis de classe são para atributos e métodos
compartilhados por todas as instâncias da classe:

Classe Cão:

tipo = 'canino' # variável de classe compartilhada por todas as instâncias

def __init__(self, name): self.name = name #


variável de instância única para cada instância

>>> d = Dog('Fido') >>> e =


Dog('Buddy') >>> d.kind
# compartilhado por todos os cães
'canino'
>>> e.kind # compartilhado por todos os cães
'canino'
>>> d.name # exclusivo para d
'Fido'
>>> e.name # exclusivo para e
'Companheiro'

Conforme discutido em A Word About Names and Objects, os dados compartilhados podem ter efeitos surpreendentes ao envolver objetos
mutáveis , como listas e dicionários. Por exemplo, a lista de truques no código a seguir não deve ser usada como uma variável de classe porque
apenas uma única lista seria compartilhada por todas as instâncias de Dog :

82 Capítulo 9. Aulas
Machine Translated by Google

Tutorial do Python, versão 3.11.3

Classe Cão:

truques = [] # uso errado de uma variável de classe

def __init__(auto, nome):


self.name = nome

def add_trick(auto, truque):


self.tricks.append(truque)

>>> d = Dog('Fido') >>> e =


Dog('Buddy') >>> d.add_trick('roll
over') >>> e.add_trick('fingir de morto') >>>
d .truques # compartilhados inesperadamente
por todos os cães
['rolar', 'fingir de morto']

O design correto da classe deve usar uma variável de instância:

Classe Cão:

def __init__(self, nome): self.name =


nome
self.truques = [] # cria uma nova lista vazia para cada cão

def add_trick(auto, truque):


self.tricks.append(truque)

>>> d = Dog('Fido') >>> e =


Dog('Buddy') >>> d.add_trick('roll
over') >>> e.add_trick('fingir de morto') >>>
d .truques

['roll over'] >>>


e.tricks
['fingir de morto']

9.4 Observações Aleatórias

Se o mesmo nome de atributo ocorrer em uma instância e em uma classe, a pesquisa de atributo priorizará a instância:

>>> Classe Armazém:


... propósito = 'armazenamento'
... região = 'oeste'
...
>>> w1 = Warehouse() >>>
print(w1.purpose, w1.region) armazenamento oeste
>>> w2 =
Warehouse()
>>> w2.region = 'east' >>>
print(w2.purpose, w2.region) storage east

Os atributos de dados podem ser referenciados por métodos, bem como por usuários comuns (“clientes”) de um objeto. Em outras palavras, as
classes não são utilizáveis para implementar tipos de dados abstratos puros. Na verdade, nada em Python torna possível forçar a ocultação de dados

9.4. Observações aleatórias 83


Machine Translated by Google

Tutorial do Python, versão 3.11.3

- é tudo baseado em convenções. (Por outro lado, a implementação do Python, escrita em C, pode ocultar completamente os detalhes da
implementação e controlar o acesso a um objeto, se necessário; isso pode ser usado por extensões do Python escritas em C.)

Os clientes devem usar os atributos de dados com cuidado — os clientes podem bagunçar as invariantes mantidas pelos métodos marcando
seus atributos de dados. Observe que os clientes podem adicionar seus próprios atributos de dados a um objeto de instância sem afetar a
validade dos métodos, desde que os conflitos de nome sejam evitados — novamente, uma convenção de nomenclatura pode evitar muitas dores
de cabeça aqui.

Não há abreviação para referenciar atributos de dados (ou outros métodos!) de dentro dos métodos. Acho que isso realmente aumenta a
legibilidade dos métodos: não há chance de confundir variáveis locais e variáveis de instância ao examinar um método.

Frequentemente, o primeiro argumento de um método é chamado self. Isso nada mais é do que uma convenção: o nome self não tem
absolutamente nenhum significado especial para Python. Observe, no entanto, que, ao não seguir a convenção, seu código pode ser menos
legível para outros programadores Python, e também é concebível que um programa de navegador de classe possa ser escrito com base em tal
convenção.

Qualquer objeto de função que seja um atributo de classe define um método para instâncias dessa classe. Não é necessário que a definição da
função esteja textualmente incluída na definição da classe: atribuir um objeto de função a uma variável local na classe também é aceitável.
Por exemplo:

# Função definida fora da classe


def f1(auto, x, y): return min(x,
x+y)

classe C:
f = f1

def g(auto):
return 'olá mundo'

h=g

Agora f, g e h são todos atributos da classe C que se referem a objetos de função e, consequentemente, são todos métodos de instâncias de C
— h sendo exatamente equivalente a g. Observe que essa prática geralmente serve apenas para confundir o leitor de um programa.

Métodos podem chamar outros métodos usando atributos de método do argumento self:

saco de classe :
def __init__(self): self.data = []

def add(self, x):


self.data.append(x)

def adicionar duas vezes(self, x):


self.add(x)
self.add(x)

Métodos podem fazer referência a nomes globais da mesma forma que funções comuns. O escopo global associado a um método é o módulo
que contém sua definição. (Uma classe nunca é usada como um escopo global.) Embora raramente se encontre uma boa razão para usar dados
globais em um método, há muitos usos legítimos do escopo global: por um lado, funções e módulos importados para o escopo global podem ser
usado por métodos, bem como funções e classes definidas nele. Normalmente, a própria classe que contém o método é definida nesse escopo
global e, na próxima seção, encontraremos alguns bons motivos pelos quais um método deseja referenciar sua própria classe.

Cada valor é um objeto e, portanto, possui uma classe (também chamada de tipo). Ele é armazenado como object.__class__.

84 Capítulo 9. Aulas
Machine Translated by Google

Tutorial do Python, versão 3.11.3

9.5 Herança

Obviamente, um recurso de linguagem não seria digno do nome “classe” sem o suporte à herança. A sintaxe para uma definição de classe
derivada se parece com isto:

class DerivedClassName(BaseClassName):
<declaração-1>
.
.
.
<declaração-N>

O nome BaseClassName deve ser definido em um escopo contendo a definição de classe derivada. No lugar de um nome de classe base, outras
expressões arbitrárias também são permitidas. Isso pode ser útil, por exemplo, quando a classe base é definida em outro módulo:

class DerivedClassName(modname.BaseClassName):

A execução de uma definição de classe derivada procede da mesma forma que para uma classe base. Quando o objeto de classe é construído,
a classe base é lembrada. Isso é usado para resolver referências de atributos: se um atributo solicitado não for encontrado na classe, a pesquisa
prossegue para procurar na classe base. Essa regra é aplicada recursivamente se a própria classe base for derivada de alguma outra classe.

Não há nada de especial na instanciação de classes derivadas: DerivedClassName() cria uma nova instância da classe. As referências de método
são resolvidas da seguinte forma: o atributo de classe correspondente é pesquisado, descendo na cadeia de classes base, se necessário, e a
referência de método é válida se isso produzir um objeto de função.

Classes derivadas podem substituir métodos de suas classes base. Como os métodos não têm privilégios especiais ao chamar outros métodos
do mesmo objeto, um método de uma classe base que chama outro método definido na mesma classe base pode acabar chamando um método
de uma classe derivada que o substitui. (Para programadores C++: todos os métodos em Python são efetivamente virtuais.)

Um método de substituição em uma classe derivada pode, de fato, querer estender em vez de simplesmente substituir o método de classe base
com o mesmo nome. Existe uma maneira simples de chamar o método da classe base diretamente: basta chamar BaseClassName.
nomedométodo(self, argumentos). Ocasionalmente, isso também é útil para os clientes. (Observe que isso só funciona se a classe base estiver
acessível como BaseClassName no escopo global.)

Python tem duas funções integradas que funcionam com herança:

• Use isinstance() para verificar o tipo de uma instância: isinstance(obj, int) será True somente se obj. __class__ é int ou alguma classe
derivada de int.

• Use issubclass() para verificar a herança de classe: issubclass(bool, int) é True, pois bool é uma subclasse de int. No entanto,
issubclass(float, int) é False, pois float não é uma subclasse de int.

9.5.1 Herança Múltipla

O Python também oferece suporte a uma forma de herança múltipla. Uma definição de classe com várias classes base se parece com isto:

class DerivedClassName(Base1, Base2, Base3): <statement-1>

.
.
.
<declaração-N>

9.5. Herança 85
Machine Translated by Google

Tutorial do Python, versão 3.11.3

Para a maioria das finalidades, nos casos mais simples, você pode pensar na pesquisa de atributos herdados de uma classe pai como
profundidade primeiro, da esquerda para a direita, não pesquisando duas vezes na mesma classe onde há uma sobreposição na hierarquia.
Assim, se um atributo não for encontrado em DerivedClassName, ele é buscado na Base1, depois (recursivamente) nas classes base da
Base1, e se não for encontrado lá, é buscado na Base2, e assim sucessivamente.

Na verdade, é um pouco mais complexo do que isso; a ordem de resolução do método muda dinamicamente para suportar chamadas
cooperativas para super(). Essa abordagem é conhecida em algumas outras linguagens de herança múltipla como call-next-method e é
mais poderosa do que a superchamada encontrada em linguagens de herança única.

A ordenação dinâmica é necessária porque todos os casos de herança múltipla exibem um ou mais relacionamentos de diamante (onde
pelo menos uma das classes pai pode ser acessada por meio de vários caminhos da classe inferior). Por exemplo, todas as classes herdam
do objeto, portanto, qualquer caso de herança múltipla fornece mais de um caminho para alcançar o objeto. Para evitar que as classes base
sejam acessadas mais de uma vez, o algoritmo dinâmico lineariza a ordem de busca de forma a preservar a ordem da esquerda para a
direita especificada em cada classe, que chama cada pai apenas uma vez e que é monotônico (o que significa que uma classe pode ser
subclasse sem afetar a ordem de precedência de seus pais). Juntas, essas propriedades tornam possível projetar classes confiáveis e
extensíveis com herança múltipla. Para obter mais detalhes, consulte https: //www.python.org/download/releases/2.3/mro/.

9.6 Variáveis Privadas

Variáveis de instância “privadas” que não podem ser acessadas exceto de dentro de um objeto não existem em Python. No entanto, existe
uma convenção que é seguida pela maioria dos códigos Python: um nome prefixado com um sublinhado (por exemplo, _spam) deve ser
tratado como uma parte não pública da API (seja uma função, um método ou um membro de dados) . Deve ser considerado um detalhe de
implementação e sujeito a alterações sem aviso prévio.

Uma vez que existe um caso de uso válido para membros privados de classe (ou seja, para evitar conflitos de nome de nomes com nomes
definidos por subclasses), há suporte limitado para tal mecanismo, chamado alteração de nome . Qualquer identificador no formato __spam
(pelo menos dois sublinhados à esquerda, no máximo um sublinhado à direita) é textualmente substituído por _classname__spam, em que
classname é o nome da classe atual com o(s) sublinhado(s) inicial(is) removido(s). Essa alteração é feita sem levar em conta a posição
sintática do identificador, desde que ocorra dentro da definição de uma classe.

A confusão de nomes é útil para permitir que as subclasses substituam os métodos sem interromper as chamadas de método intraclasse. Por exemplo:

Mapeamento de classe :
def __init__(self, iterável):
self.items_list = []
self.__update(iterável)

def update(auto, iterável):


para item em iterável:

self.items_list.append(item)

__update = update # cópia privada do método update() original

class MappingSubclass(Mapping):

def update(self, keys, values): # fornece nova assinatura


para update() # mas não quebra __init__() para item em zip(keys,
values):

self.items_list.append(item)

O exemplo acima funcionaria mesmo se MappingSubclass introduzisse um identificador __update, pois ele foi substituído por
_Mapping__update na classe Mapping e _MappingSubclass__update na classe MappingSubclass, respectivamente.

86 Capítulo 9. Aulas
Machine Translated by Google

Tutorial do Python, versão 3.11.3

Observe que as regras de mutilação são projetadas principalmente para evitar acidentes; ainda é possível acessar ou modificar uma
variável considerada privada. Isso pode até ser útil em circunstâncias especiais, como no depurador.

Observe que o código passado para exec() ou eval() não considera o nome de classe da classe de chamada como sendo a classe atual;
isso é semelhante ao efeito da instrução global, cujo efeito também é restrito ao código compilado em byte. A mesma restrição se aplica
a getattr(), setattr() e delattr(), bem como ao referenciar __dict__ diretamente.

9.7 Probabilidades e Fins

Às vezes é útil ter um tipo de dados semelhante ao “registro” Pascal ou “estrutura” C, agrupando alguns itens de dados nomeados. A
abordagem idiomática é usar dataclasses para esta finalidade:

de classes de dados importar classe de dados

@dataclass class
Funcionário:
nome: str
dept: str salário:
int

>>> john = Employee('john', 'computer lab', 1000) >>> john.dept 'computer lab' >>> john.salary
1000

Um pedaço de código Python que espera um determinado tipo de dado abstrato pode frequentemente ser passado para uma classe
que emula os métodos desse tipo de dado. Por exemplo, se você tem uma função que formata alguns dados de um objeto de arquivo,
você pode definir uma classe com os métodos read() e readline() que obtêm os dados de um buffer de string e passam como um argumento.

Objetos de método de instância também têm atributos: m.__self__ é o objeto de instância com o método m() e m. __func__ é o objeto
de função correspondente ao método.

9.8 Iteradores

A esta altura você já deve ter notado que a maioria dos objetos container pode sofrer um loop usando uma instrução for:

para o elemento em [1, 2, 3]:


imprimir(elemento)
para o elemento em (1, 2, 3):
print(element) para chave
em {'one':1, 'two':2}:
imprimir(chave)
para char em "123":
print(char) for line
in open("myfile.txt"): print(line, end='')

Esse estilo de acesso é claro, conciso e conveniente. O uso de iteradores permeia e unifica Python. Nos bastidores, a instrução for
chama iter() no objeto contêiner. A função retorna um objeto iterador que define o método __next__() que acessa elementos no container
um por vez. Quando não há mais elementos, __next__() gera uma exceção StopIteration que diz ao loop for para terminar. Você pode
chamar o método __next__() usando a função interna next(); este exemplo mostra como tudo funciona:

9.7. Miudezas 87
Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> s = 'abc'
>>> it = iter(es) >>> it

<str_iterator objeto em 0x10c90e650> >>> next(it)

'a'
>>> próximo(a)
'b'
>>> próximo(a)
'c'
>>> próximo(a)
Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
próximo(a)
StopIteration

Tendo visto a mecânica por trás do protocolo do iterador, é fácil adicionar o comportamento do iterador às suas
classes. Defina um método __iter__() que retorna um objeto com um método __next__(). Se a classe definir __next__(),
então __iter__() pode apenas retornar self:

Classe Inversa:
"""Iterador para repetir uma sequência para trás.""" def __init__(self, data): self.data = data

self.index = len(dados)

def __iter__(auto):
retornar a si mesmo

def __next__(self):
se self.index == 0:
raise StopIteration self.index =
self.index - 1
return self.data[self.index]

>>> rev = Reverse('spam') >>> iter(rev)


<__main__.Reverse
object at 0x00A1DB50> >>> for char in rev:

... print(char)
...
m
a
p
s

88 Capítulo 9. Aulas
Machine Translated by Google

Tutorial do Python, versão 3.11.3

9.9 Geradores
Geradores são uma ferramenta simples e poderosa para criar iteradores. Eles são escritos como funções regulares, mas usam a instrução
yield sempre que desejam retornar dados. Cada vez que next() é chamado, o gerador continua de onde parou (lembra todos os valores de
dados e qual instrução foi executada pela última vez). Um exemplo mostra que os geradores podem ser trivialmente fáceis de criar:

def reverse(data): para


índice em range(len(data)-1, -1, -1):
dados de rendimento [índice]

>>> para char in reverse('golf'): print(char)


...
...
f
eu

o
g

Tudo o que pode ser feito com geradores também pode ser feito com iteradores baseados em classe, conforme descrito na seção anterior.
O que torna os geradores tão compactos é que os métodos __iter__() e __next__() são criados automaticamente.

Outro recurso importante é que as variáveis locais e o estado de execução são salvos automaticamente entre as chamadas. Isso tornou a
função mais fácil de escrever e muito mais clara do que uma abordagem usando variáveis de instância como self.index e self. dados.

Além da criação automática de método e salvamento do estado do programa, quando os geradores terminam, eles aumentam StopIteration
automaticamente. Em combinação, esses recursos facilitam a criação de iteradores sem mais esforço do que escrever uma função regular.

9.10 Expressões Geradoras


Alguns geradores simples podem ser codificados sucintamente como expressões usando uma sintaxe semelhante a listas de compreensão,
mas com parênteses em vez de colchetes. Essas expressões são projetadas para situações em que o gerador é usado imediatamente por
uma função envolvente. As expressões do gerador são mais compactas, mas menos versáteis do que as definições do gerador completo e
tendem a ser mais amigáveis à memória do que as compreensões de lista equivalentes.

Exemplos:

>>> soma(i*i para i no intervalo(10)) 285 # soma dos quadrados

>>> xvec = [10, 20, 30] >>> yvec =


[7, 5, 3] >>> sum(x*y for x,y in
zip(xvec, yvec)) 260 # produto escalar

>>> unique_words = set(palavra por linha na página por palavra na linha.split())

>>> orador da turma = max((aluno.gpa, aluno.nome) para aluno em graduados)

>>> data = 'golf' >>>


list(data[i] for i in range(len(data)-1, -1, -1)) ['f', 'l', 'o', ' g']

9.9. Geradores 89
Machine Translated by Google

Tutorial do Python, versão 3.11.3

90 Capítulo 9. Aulas
Machine Translated by Google

CAPÍTULO

DEZ

BREVE TOUR PELA BIBLIOTECA PADRÃO

10.1 Interface do Sistema Operacional

O módulo os fornece dezenas de funções para interagir com o sistema operacional:

>>> import os >>>


os.getcwd() # Retorna o diretório de trabalho atual
'C:\\Python311' >>>
os.chdir('/server/accesslogs') # Altere o diretório de trabalho atual # Execute o comando mkdir no shell do
sistema >>> os.system('mkdir today')
0

Certifique-se de usar o estilo import os em vez de from os import *. Isso evitará que os.open() sombreie a função interna open() que opera de
maneira muito diferente.

As funções embutidas dir() e help() são úteis como auxílios interativos para trabalhar com módulos grandes como os:

>>> import os >>>


dir(os) <retorna
uma lista de todas as funções do módulo>
>>> help(os)
<retorna uma extensa página de manual criada a partir das docstrings do módulo>

Para tarefas diárias de gerenciamento de arquivos e diretórios, o módulo shutil fornece uma interface de nível superior que é mais fácil de usar:

>>> import shutil >>>


shutil.copyfile('data.db', 'archive.db') 'archive.db'

>>> shutil.move('/build/executables', 'installdir') 'installdir'

10.2 Curingas de Arquivo

O módulo glob fornece uma função para criar listas de arquivos a partir de pesquisas curinga de diretório:

>>> import glob >>>


glob.glob('*.py') ['primes.py',
'random.py', 'quote.py']

91
Machine Translated by Google

Tutorial do Python, versão 3.11.3

10.3 Argumentos da Linha de Comando

Os scripts de utilitários comuns geralmente precisam processar argumentos de linha de comando. Esses argumentos são armazenados
no atributo argv do módulo sys como uma lista. Por exemplo, a seguinte saída resulta da execução de python demo.py um dois três na
linha de comando:

>>> import sys >>>


print(sys.argv) ['demo.py',
'one', 'two', 'three']

O módulo argparse fornece um mecanismo mais sofisticado para processar argumentos de linha de comando. O script a seguir extrai
um ou mais nomes de arquivo e um número opcional de linhas a serem exibidas:

importar argparse

parser = argparse.ArgumentParser(
prog='top',
description='Mostrar linhas principais de cada arquivo')
parser.add_argument('filenames', nargs='+') parser.add_argument('-
l', '--lines', type=int, default=10) args = parser.parse_args() print(args)

Quando executado na linha de comando com python top.py --lines=5 alpha.txt beta.txt, o script define args.lines como 5 e args.filenames
como ['alpha.txt', 'beta.txt'].

10.4 Redirecionamento de saída de erro e encerramento do programa

O módulo sys também possui atributos para stdin, stdout e stderr. Este último é útil para emitir avisos e mensagens de erro para torná-
los visíveis mesmo quando o stdout foi redirecionado:

>>> sys.stderr.write('Aviso, arquivo de log não encontrado iniciando um novo \n')


Aviso, arquivo de log não encontrado iniciando um novo

A maneira mais direta de encerrar um script é usar sys.exit().

10.5 Correspondência de padrão de string

O módulo re fornece ferramentas de expressão regular para processamento avançado de strings. Para correspondência e manipulação complexas,
as expressões regulares oferecem soluções sucintas e otimizadas:

>>> import re >>>


re.findall(r'\bf[az]*', 'qual pé ou mão caiu mais rápido') ['pé', 'caiu', 'mais rápido'] >>> re.sub (r'(\b[az]
+) \1', r'\1', 'gato no chapéu') 'gato no
chapéu'

Quando apenas recursos simples são necessários, os métodos de string são preferidos porque são mais fáceis de ler e depurar:

>>> 'chá para também'.replace('também', 'dois')


'chá para dois'

92 Capítulo 10. Breve Tour pela Biblioteca Padrão


Machine Translated by Google

Tutorial do Python, versão 3.11.3

10.6 Matemática

O módulo math dá acesso às funções subjacentes da biblioteca C para matemática de ponto flutuante:

>>> import math >>>


math.cos(math.pi / 4)
0.70710678118654757
>>> math.log(1024, 2) 10.0

O módulo aleatório fornece ferramentas para fazer seleções aleatórias:

>>> import random >>>


random.choice(['apple', 'pear', 'banana']) 'apple' >>>

random.sample(range(100), 10) [30, 83, 16, 4, 8, # amostragem sem reposição


81, 41, 50, 18, 33] # random float >>> random.random()

0,17970987693706186
>>> aleatório. randrange(6) 4 # inteiro aleatório escolhido de range(6)

O módulo de estatísticas calcula propriedades estatísticas básicas (média, mediana, variância, etc.) de dados numéricos:

>>> importar estatísticas >>>


dados = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5] >>> statistics.mean(data)
1.6071428571428572

>>> estatísticas.mediana(dados) 1,25

>>> estatísticas.variância(dados)
1.3720238095238095

O projeto SciPy <https://scipy.org> tem muitos outros módulos para cálculos numéricos.

10.7 Acesso à Internet

Existem vários módulos para acessar a Internet e processar protocolos de Internet. Dois dos mais simples são urllib.request para
recuperar dados de URLs e smtplib para enviar e-mail:

>>> from urllib.request import urlopen >>> with


urlopen('http://worldtimeapi.org/api/timezone/etc/UTC.txt') como resposta:
... para linha em resposta:
... line = line.decode() if # Converte bytes em str
... line.startswith('datetime'): print(line.rstrip())
... # Remova a nova linha à direita
...
data e hora: 2022-01-01T01:36:47.689215+00:00

>>> import smtplib >>>


server = smtplib.SMTP('localhost') >>>
server.sendmail('soothsayer@example.org', 'jcaesar@example.org', ... """To: jcaesar @example.org ... De:
adivinho@example.org

...
(continua na próxima página)

10.6. Matemática 93
Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


... Cuidado com os idos de março.

... """) >>>


servidor.quit()

(Observe que o segundo exemplo precisa de um servidor de correio em execução no localhost.)

10.8 Datas e Horários

O módulo datetime fornece classes para manipular datas e horas de maneiras simples e complexas. Embora a aritmética de data
e hora seja suportada, o foco da implementação está na extração eficiente de membros para formatação e manipulação de saída.
O módulo também oferece suporte a objetos com reconhecimento de fuso horário.

>>> # datas são facilmente construídas e formatadas >>> from datetime import
date >>> now = date.today()

>>> agora
datetime.date(2003, 12, 2) >>>
now.strftime("%m-%d-%y. %d %b %Y é um %A no dia %d de %B.")
'12-02-03. 02 de dezembro de 2003 é uma terça-feira no dia 02 de dezembro.'

>>> # datas suportam aritmética do calendário >>> aniversário =


data(1964, 7, 31) >>> idade = agora - aniversário >>>
idade.dias 14368

10.9 Compressão de Dados

Os formatos comuns de arquivamento e compactação de dados são suportados diretamente por módulos, incluindo: zlib, gzip,
bz2, lzma, zipfile e tarfile.

>>> import zlib >>> s =


b'witch que tem quais bruxas relógio de pulso'
>>> len(s) 41

>>> t = zlib.compress(s) >>> len(t)

37
>>> zlib.decompress(t) b'bruxa que
tem o relógio de pulso de qual bruxa'
>>> zlib.crc32(s) 226805979

94 Capítulo 10. Breve Tour pela Biblioteca Padrão


Machine Translated by Google

Tutorial do Python, versão 3.11.3

10.10 Medição de Desempenho

Alguns usuários de Python desenvolvem um profundo interesse em conhecer o desempenho relativo de diferentes abordagens para o mesmo
problema. O Python fornece uma ferramenta de medição que responde a essas perguntas imediatamente.

Por exemplo, pode ser tentador usar o recurso de empacotamento e descompactação de tuplas em vez da abordagem tradicional de troca de
argumentos. O módulo timeit demonstra rapidamente uma modesta vantagem de desempenho:

>>> from timeit import Timer >>> Timer('t=a;


a=b; b=t', 'a=1; b=2').timeit()
0,57535828626024577
>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
0,54962537085770791

Em contraste com o nível fino de granularidade do timeit, os módulos profile e pstats fornecem ferramentas para identificar seções críticas de
tempo em blocos maiores de código.

10.11 Controle de Qualidade

Uma abordagem para desenvolver software de alta qualidade é escrever testes para cada função à medida que ela é desenvolvida e executar esses
testes frequentemente durante o processo de desenvolvimento.

O módulo doctest fornece uma ferramenta para escanear um módulo e validar testes embutidos nas docstrings de um programa.
A construção do teste é tão simples quanto recortar e colar uma chamada típica junto com seus resultados na docstring. Isso melhora a
documentação fornecendo ao usuário um exemplo e permite que o módulo doctest certifique-se de que o código permaneça fiel à documentação:

def average(values): """Calcula a


média aritmética de uma lista de números.

>>> print(average([20, 30, 70])) 40,0

"""

return sum(valores) / len(valores)

import doctest
doctest.testmod() # valida automaticamente os testes embutidos

O módulo unittest não é tão fácil quanto o módulo doctest, mas permite que um conjunto mais abrangente de testes seja mantido em um
arquivo separado:

importar unidade de teste

class TestStatisticalFunctions(unittest.TestCase):

def test_average(self):
self.assertEqual(average([20, 30, 70]), 40.0) self.assertEqual(round(average([1,
5, 7]), 1), 4.3) com self.assertRaises(ZeroDivisionError):

média([])
com self.assertRaises(TypeError): average(20, 30, 70)

unittest.main() # Chamar a partir da linha de comando invoca todos os testes

10.10. Medição de desempenho 95


Machine Translated by Google

Tutorial do Python, versão 3.11.3

10.12 Baterias Incluídas


Python tem uma filosofia de “pilhas incluídas”. Isso é melhor visto através dos recursos sofisticados e robustos de seus pacotes maiores. Por exemplo:

• Os módulos xmlrpc.client e xmlrpc.server transformam a implementação de chamadas de procedimentos remotos em um


tarefa mais trivial. Apesar dos nomes dos módulos, nenhum conhecimento direto ou manuseio de XML é necessário.

• O pacote de e-mail é uma biblioteca para gerenciar mensagens de e-mail, incluindo MIME e outros RFC documentos de mensagens baseados
em 2822. Ao contrário de smtplib e poplib, que realmente enviam e recebem mensagens, o pacote de e-mail possui um conjunto de ferramentas
completo para construir ou decodificar estruturas de mensagens complexas (incluindo anexos) e para implementar codificação de Internet e
protocolos de cabeçalho.

• O pacote json oferece suporte robusto para analisar esse popular formato de intercâmbio de dados. O módulo csv oferece suporte à leitura e
gravação direta de arquivos no formato Comma-Separated Value, comumente suportado por bancos de dados e planilhas. O processamento
XML é suportado pelos pacotes xml.etree.ElementTree, xml.dom e xml.sax. Juntos, esses módulos e pacotes simplificam muito o intercâmbio
de dados entre aplicativos Python e outras ferramentas.

• O módulo sqlite3 é um wrapper para a biblioteca de banco de dados SQLite, fornecendo um banco de dados persistente que pode ser
atualizado e acessado usando uma sintaxe SQL ligeiramente fora do padrão.

• A internacionalização é suportada por vários módulos, incluindo gettext, locale e o pacote de codecs
idade.

96 Capítulo 10. Breve Tour pela Biblioteca Padrão


Machine Translated by Google

CAPÍTULO

ONZE

BREVE TOUR PELA BIBLIOTECA PADRÃO — PARTE II

Este segundo tour cobre módulos mais avançados que dão suporte às necessidades de programação profissional. Esses módulos raramente
ocorrem em pequenos scripts.

11.1 Formatação de saída

O módulo reprlib fornece uma versão de repr() personalizada para exibições abreviadas de contêineres grandes ou profundamente aninhados:

>>> import reprlib >>>


reprlib.repr(set('supercalifragilisticexpialidocious')) "{'a', 'c', 'd', 'e', 'f', 'g', ...}"

O módulo pprint oferece um controle mais sofisticado sobre a impressão de objetos integrados e definidos pelo usuário de uma forma legível pelo
interpretador. Quando o resultado é maior que uma linha, a “impressora bonita” adiciona quebras de linha e recuo para revelar mais claramente a
estrutura de dados:

>>> import pprint >>> t


= [[[['preto', 'ciano'], 'branco', ['verde', 'vermelho']], [['magenta', 'amarelo'], ' azul']]]
...
...
>>> pprint.pprint(t, width=30) [[[['preto', 'ciano'],
'branco', ['verde', 'vermelho']],
[['magenta',
'amarelo' ], 'azul']]]

O módulo textwrap formata parágrafos de texto para caber em uma determinada largura de tela:

>>> import textwrap >>>


doc = """O método wrap() é exatamente como fill() exceto que retorna ... uma lista de strings em vez de uma
grande string com novas linhas para separar ... as linhas quebradas ."""

...
>>> print(textwrap.fill(doc, width=40))
O método wrap() é exatamente como fill(), exceto que ele
retorna uma lista de strings em vez de uma grande string com
novas linhas para separar as linhas quebradas.

O módulo de localidade acessa um banco de dados de formatos de dados específicos da cultura. O atributo de agrupamento da função de formato
de localidade fornece uma maneira direta de formatar números com separadores de grupo:

97
Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> import locale >>>


locale.setlocale(locale.LC_ALL, 'English_United States.1252')
'English_United States.1252' >>> conv =
locale.localeconv() >>> x = 1234567.8 # obtém um mapeamento de convenções

>>> locale.format("%d", x, grouping=True) '1.234.567' >>>

locale.format_string("%s%.*f", (conv['currency_symbol'], conv['frac_digits' ], x), agrupamento = Verdadeiro)


...
'$ 1.234.567,80'

11.2 Modelagem

O módulo string inclui uma classe Template versátil com uma sintaxe simplificada adequada para edição por usuários finais.
Isso permite que os usuários personalizem seus aplicativos sem precisar alterá-los.

O formato usa nomes de espaços reservados formados por $ com identificadores Python válidos (caracteres alfanuméricos e sublinhados).
Cercar o espaço reservado com colchetes permite que ele seja seguido por mais letras alfanuméricas sem espaços intermediários.
Escrever $$ cria um único $ com escape:

>>> from string import Template >>> t = Template('$


{village}folk send $$10 to $cause.') >>> t.substitute(village='Nottingham', cause='the ditch fund')

'Nottinghamfolk envia US$ 10 para o fundo de fosso.'

O método replace() gera um KeyError quando um espaço reservado não é fornecido em um dicionário ou um argumento de palavra-chave.
Para aplicativos estilo mala direta, os dados fornecidos pelo usuário podem estar incompletos e o método safe_substitute() pode ser mais
apropriado — ele deixará espaços reservados inalterados se os dados estiverem ausentes:

>>> t = Template('Devolver o $item ao $dono.') >>> d = dict(item=' andorinha


sem carga') >>> t.substitute(d)

Traceback (última chamada mais recente):


...
KeyError: 'owner' >>>
t.safe_substitute(d)
'Devolva a andorinha vazia ao $proprietário.'

As subclasses de modelo podem especificar um delimitador personalizado. Por exemplo, um utilitário de renomeação em lote para um navegador de fotos pode
optar por usar sinais de porcentagem para espaços reservados, como data atual, número de sequência de imagem ou formato de arquivo:

>>> import time, os.path >>> photofiles


= ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg'] >>> class BatchRename(Template):

... delimitador = '%'


...
>>> fmt = input('Digite o estilo de renomeação (%d-date %n-seqnum %f-format): ')
Insira o estilo de renomeação (%d-date %n-seqnum %f-format): Ashley_%n%f

>>> t = BatchRename(fmt) >>> date =


time.strftime('%d%b%y') >>> for i, filename in
enumerate(photofiles): base, ext = os.path.splitext( filename) newname =
... t.substitute(d=date, n=i, f=ext)
...
(continua na próxima página)

98 Capítulo 11. Breve Tour pela Biblioteca Padrão — Parte II


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

... print('{0} --> {1}'.format(filename, newname))

img_1074.jpg --> Ashley_0.jpg img_1076.jpg -->


Ashley_1.jpg img_1077.jpg --> Ashley_2.jpg

Outra aplicação para modelagem é separar a lógica do programa dos detalhes de vários formatos de saída. Isso torna possível substituir modelos
personalizados para arquivos XML, relatórios de texto simples e relatórios da Web em HTML.

11.3 Trabalhando com layouts de registro de dados binários

O módulo struct fornece as funções pack() e unpack() para trabalhar com registros binários de comprimento variável para mats. O exemplo a seguir
mostra como percorrer as informações do cabeçalho em um arquivo ZIP sem usar o módulo zipfile. Os códigos de pacote "H" e "I" representam
números não assinados de dois e quatro bytes, respectivamente. O "<" indica que eles são de tamanho padrão e na ordem de bytes little-endian:

estrutura de importação

com open('myfile.zip', 'rb') como f:


dados = f.read()

início = 0
para i no intervalo (3): início # mostra os 3 primeiros cabeçalhos de arquivo
+= 14
campos = struct.unpack('<IIIHH', data[start:start+16]) crc32, comp_size, uncomp_size,
filenamesize, extra_size = campos

início += 16
filename = data[start:start+filenamesize] start += filenamesize

extra = data[start:start+extra_size] print(filename, hex(crc32),


comp_size, uncomp_size)

início += extra_size + comp_size # pular para o próximo cabeçalho

11.4 Multi-threading

Threading é uma técnica para desacoplar tarefas que não são sequencialmente dependentes. Os encadeamentos podem ser usados para melhorar a
capacidade de resposta de aplicativos que aceitam a entrada do usuário enquanto outras tarefas são executadas em segundo plano. Um caso de uso
relacionado está executando I/O em paralelo com cálculos em outro thread.

O código a seguir mostra como o módulo de encadeamento de alto nível pode executar tarefas em segundo plano enquanto o programa principal
continua em execução:

importar segmentação, arquivo zip

classe AsyncZip(threading.Thread):
def __init__(self, infile, outfile): threading.Thread.__init__(self)
self.infile = infile

self.outfile = outfile
(continua na próxima página)

11.3. Trabalhando com layouts de registro de dados binários 99


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

def executar(auto):
f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED) f.write(self.infile) f.close() print('Finished background zip
of:', self.infile)

background = AsyncZip('mydata.txt', 'myarchive.zip') background.start() print('O programa principal


continua rodando em primeiro
plano.')

O programa principal esperou # Aguarde a conclusão da tarefa em segundo plano background.join() print('
até que o segundo plano fosse concluído.')

O principal desafio de aplicativos multiencadeados é coordenar encadeamentos que compartilham dados ou outros recursos. Para esse fim, o
módulo de encadeamento fornece várias primitivas de sincronização, incluindo bloqueios, eventos, variáveis de condição e semáforos.

Embora essas ferramentas sejam poderosas, pequenos erros de design podem resultar em problemas difíceis de reproduzir. Portanto, a abordagem
preferencial para a coordenação de tarefas é concentrar todo o acesso a um recurso em um único thread e, em seguida, usar o módulo de fila para
alimentar esse thread com solicitações de outros threads. Os aplicativos que usam objetos Queue para comunicação e coordenação entre threads
são mais fáceis de projetar, mais legíveis e mais confiáveis.

11.5 Registro
O módulo de registro oferece um sistema de registro completo e flexível. Na sua forma mais simples, as mensagens de log são enviadas para um
arquivo ou para sys.stderr:

import logging
logging.debug(' Informações de depuração') logging.info('Mensagem
informativa') logging.warning('Aviso: arquivo de configuração %s não
encontrado', 'server.conf') logging.error(' Ocorreu um erro') logging.critical(' Erro crítico -- desligando')

Isso produz a seguinte saída:

AVISO:root:Aviso:arquivo de configuração server.conf não encontrado ERRO:root:Ocorreu um erro

CRÍTICO:raiz:Erro crítico -- desligando

Por padrão, as mensagens informativas e de depuração são suprimidas e a saída é enviada para o erro padrão. Outras opções de saída incluem
roteamento de mensagens por e-mail, datagramas, soquetes ou para um servidor HTTP. Novos filtros podem selecionar roteamento diferente com
base na prioridade da mensagem: DEBUG, INFO, WARNING, ERROR e CRITICAL.

O sistema de registro pode ser configurado diretamente do Python ou pode ser carregado de um arquivo de configuração editável pelo usuário
para registro personalizado sem alterar o aplicativo.

100 Capítulo 11. Breve Tour pela Biblioteca Padrão — Parte II


Machine Translated by Google

Tutorial do Python, versão 3.11.3

11.6 Referências Fracas

Python faz gerenciamento automático de memória (contagem de referência para a maioria dos objetos e coleta de lixo para eliminar ciclos). A
memória é liberada logo após a última referência a ela ter sido eliminada.

Essa abordagem funciona bem para a maioria dos aplicativos, mas ocasionalmente há a necessidade de rastrear objetos apenas enquanto
estiverem sendo usados por outra coisa. Infelizmente, apenas rastreá-los cria uma referência que os torna permanentes. O módulo fracoref fornece
ferramentas para rastrear objetos sem criar uma referência. Quando o objeto não é mais necessário, ele é removido automaticamente de uma
tabela de referência fraca e um retorno de chamada é acionado para objetos de referência fraca. Aplicações típicas incluem cache de objetos que
são caros de criar:

>>> importar fracoref, gc >>>


classe A:
... def __init__(auto, valor):
... auto.valor = valor
... def __repr__(self): return
... str(self.value)
...
>>> a = A(10) # crie uma referência >>> d = fracaref.WeakValueDictionary() >>>
d['primary'] = a >>> d['primary'] 10
# não cria uma referência
# busca o objeto se ele ainda estiver vivo

>>> de um # remove a única referência


>>> gc.collect() 0 # execute a coleta de lixo imediatamente

>>> d['primário'] # entrada foi removida automaticamente


Traceback (última chamada mais recente):
Arquivo "<stdin>", linha 1, em <module>
d['primário'] # a entrada foi removida automaticamente Arquivo
"C:/python311/lib/weakref.py", linha 46, em __getitem__
o = self.data[chave]()
KeyError: 'primário'

11.7 Ferramentas para trabalhar com listas

Muitas necessidades de estrutura de dados podem ser atendidas com o tipo de lista integrado. No entanto, às vezes há necessidade de
implementações alternativas com diferentes compensações de desempenho.

O módulo array fornece um objeto array() que é como uma lista que armazena apenas dados homogêneos e os armazena de forma mais
compacta. O exemplo a seguir mostra uma matriz de números armazenados como números binários não assinados de dois bytes (typecode "H")
em vez dos 16 bytes usuais por entrada para listas regulares de objetos Python int:

>>> from array import array >>> a =


array('H', [4000, 10, 700, 22222]) >>> sum(a) 26932

>>> a[1:3]
array('H', [10, 700])

O módulo de coleções fornece um objeto deque() que é como uma lista com anexos e pops mais rápidos do lado esquerdo, mas pesquisas mais
lentas no meio. Esses objetos são adequados para implementar filas e pesquisas de primeira árvore amplas:

11.6. Referências fracas 101


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> from collections import deque >>> d =


deque(["task1", "task2", "task3"]) >>> d.append("task4") >>>
print("Manipulação", d. popleft())

Lidando com a tarefa1

unsearched = deque([starting_node]) def


breadth_first_search(unsearched):
node = unearched.popleft() for m in
gen_moves(node): if is_goal(m): return
m

não pesquisado.append(m)

Além de implementações de listas alternativas, a biblioteca também oferece outras ferramentas como o módulo bisect com funções para manipulação
de listas ordenadas:

>>> import bisect >>>


scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')] >>> bisect.insort( pontuações, (300, 'rubi'))

>>> pontuações

[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]

O módulo heapq fornece funções para implementar heaps com base em listas regulares. A entrada de menor valor é sempre mantida na posição
zero. Isso é útil para aplicativos que acessam repetidamente o menor elemento, mas não desejam executar uma classificação de lista completa:

>>> from heapq import heapify, heappop, heappush >>> data = [1, 3, 5, 7, 9,
2, 4, 6, 8, 0] >>> heapify(data) >>> heappush(data , -5) >>>
[heappop(data) for i in # reorganiza a lista em ordem de heap # adiciona uma nova
range(3)] # busca as três menores entrada
entradas [-5, 0, 1]

11.8 Aritmética Decimal de Ponto Flutuante

O módulo decimal oferece um tipo de dados Decimal para aritmética de ponto flutuante decimal. Comparada com a implementação interna float de
ponto flutuante binário, a classe é especialmente útil para

• aplicações financeiras e outros usos que requerem representação decimal exata,

• controle sobre a precisão,

• controle sobre o arredondamento para atender aos requisitos legais ou regulamentares,

• rastreamento de casas decimais significativas, ou

• aplicativos em que o usuário espera que os resultados coincidam com os cálculos feitos à mão.

Por exemplo, calcular um imposto de 5% sobre uma tarifa telefônica de 70 centavos fornece resultados diferentes em ponto flutuante decimal e ponto
flutuante binário. A diferença se torna significativa se os resultados forem arredondados para o centavo mais próximo:

>>> from decimal import * >>>


round(Decimal('0.70') * Decimal('1.05'), 2)
Decimais('0,74')
(continua na próxima página)

102 Capítulo 11. Breve Tour pela Biblioteca Padrão — Parte II


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

>>> redondo(0,70 * 1,05, 2) 0,73

O resultado Decimal mantém um zero à direita, inferindo automaticamente a significância de quatro casas de multiplicandos com
significância de duas casas. Decimal reproduz a matemática como feita à mão e evita problemas que podem surgir quando o ponto
flutuante binário não pode representar exatamente quantidades decimais.

A representação exata permite que a classe Decimal execute cálculos de módulo e testes de igualdade que não são adequados para ponto
flutuante binário:

>>> Decimal('1.00') % Decimal('.10')


Decimal('0,00') >>> 1,00
% 0,10
0,09999999999999995

>>> soma([Decimal('0.1')]*10) == Decimal('1.0')


Verdadeiro

>>> soma([0.1]*10) == 1.0 Falso

O módulo decimal fornece aritmética com a precisão necessária:

>>> getcontext().prec = 36 >>> Decimal(1) /


Decimal(7)
Decimal('0.142857142857142857142857142857142857')

11.8. Aritmética Decimal de Ponto Flutuante 103


Machine Translated by Google

Tutorial do Python, versão 3.11.3

104 Capítulo 11. Breve Tour pela Biblioteca Padrão — Parte II


Machine Translated by Google

CAPÍTULO

DOZE

AMBIENTES E PACOTES VIRTUAIS

12.1 Introdução

Os aplicativos Python geralmente usam pacotes e módulos que não fazem parte da biblioteca padrão. Às vezes, os aplicativos precisam de uma
versão específica de uma biblioteca, porque o aplicativo pode exigir que um bug específico seja corrigido ou o aplicativo pode ser escrito usando
uma versão obsoleta da interface da biblioteca.

Isso significa que pode não ser possível que uma instalação do Python atenda aos requisitos de todos os aplicativos. Se o aplicativo A precisar
da versão 1.0 de um determinado módulo, mas o aplicativo B precisar da versão 2.0, os requisitos estarão em conflito e a instalação da versão
1.0 ou 2.0 deixará um aplicativo incapaz de ser executado.

A solução para esse problema é criar um ambiente virtual, uma árvore de diretórios independente que contenha uma instalação do Python para
uma versão específica do Python, além de vários pacotes adicionais.

Diferentes aplicativos podem então usar diferentes ambientes virtuais. Para resolver o exemplo anterior de requisitos conflitantes, o aplicativo A
pode ter seu próprio ambiente virtual com a versão 1.0 instalada, enquanto o aplicativo B tem outro ambiente virtual com a versão 2.0. Se o
aplicativo B exigir que uma biblioteca seja atualizada para a versão 3.0, isso não afetará o ambiente do aplicativo A.

12.2 Criando Ambientes Virtuais

O módulo utilizado para criar e gerenciar ambientes virtuais é denominado venv. O venv geralmente instalará a versão mais recente do Python
disponível. Se você tiver várias versões do Python em seu sistema, poderá selecionar uma versão específica do Python executando python3 ou
qualquer outra versão desejada.

Para criar um ambiente virtual, escolha um diretório onde deseja colocá-lo e execute o módulo venv como um script com o caminho do diretório:

python -m venv tutorial-env

Isso criará o diretório tutorial-env se ele não existir e também criará diretórios dentro dele contendo uma cópia do interpretador Python e vários
arquivos de suporte.

Um local de diretório comum para um ambiente virtual é .venv. Esse nome mantém o diretório normalmente oculto em seu shell e, portanto, fora
do caminho, ao mesmo tempo em que fornece um nome que explica por que o diretório existe. Ele também evita conflito com arquivos de
definição de variável de ambiente .env que algumas ferramentas suportam.

Depois de criar um ambiente virtual, você pode ativá-lo.

No Windows, execute:

tutorial-env\Scripts\activate.bat

105
Machine Translated by Google

Tutorial do Python, versão 3.11.3

No Unix ou MacOS, execute:

source tutorial-env/bin/activate

(Este script foi escrito para o shell bash. Se você usar os shells csh ou fish , existem scripts activate.csh e activate.fish alternativos que
você deve usar).

A ativação do ambiente virtual mudará o prompt do seu shell para mostrar qual ambiente virtual você está usando e modificará o ambiente
para que a execução do python obtenha essa versão e instalação específicas do Python. Por exemplo:

$ source ~/envs/tutorial-env/bin/activate (tutorial-env) $ python


Python 3.5.1 (padrão, 6 de maio de
2016, 10:59:36)
...
>>> import sys >>>
sys.path ['', '/usr/
local/lib/python35.zip', ..., '~/envs/tutorial-env/lib/python3.5/site-
packages ']
>>>

Para desativar um ambiente virtual, digite:

desativar

no terminal.

12.3 Gerenciando Pacotes com pip


Você pode instalar, atualizar e remover pacotes usando um programa chamado pip. Por padrão, o pip instalará pacotes do Python Package
Index. Você pode navegar pelo Python Package Index acessando-o em seu navegador da web.

pip tem vários subcomandos: “install”, “uninstall”, “freeze”, etc. (Consulte o guia de índice de instalação para obter a documentação
completa do pip.)

Você pode instalar a versão mais recente de um pacote especificando o nome do pacote:

(tutorial-env) $ python -m pip install novas Coletando novas Baixando


novas-3.1.1.3.tar.gz
(136kB)
Instalando pacotes coletados: novas Executando
setup.py install for novas Instalado com sucesso
novas-3.1.1.3

Você também pode instalar uma versão específica de um pacote fornecendo o nome do pacote seguido de == e o número da versão:

(tutorial-env) $ python -m pip install requests==2.6.0 Coletando solicitações==2.6.0


Usando solicitações em cache-2.6.0-
py2.py3-none-any.whl Instalando pacotes coletados: solicitações Solicitações
instaladas com sucesso- 2.6.0

Se você executar novamente este comando, o pip notará que a versão solicitada já está instalada e não fará nada. Você pode fornecer um
número de versão diferente para obter essa versão ou pode executar python -m pip install --upgrade para atualizar o pacote para a versão
mais recente:

106 Capítulo 12. Ambientes Virtuais e Pacotes


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(tutorial-env) $ python -m pip install --upgrade requests


Solicitações de coleta
Instalando pacotes coletados: solicitações
Instalação existente encontrada: solicitações 2.6.0
Pedidos de desinstalação-2.6.0:
Pedidos desinstalados com sucesso-2.6.0
Pedidos instalados com sucesso-2.7.0

python -m pip desinstalação seguido por um ou mais nomes de pacote removerá os pacotes do ambiente virtual.

python -m pip show exibirá informações sobre um pacote específico:

(tutorial-env) $ python -m pip mostra solicitações


---

Metadata-Versão: 2.0
Nome: request Versão:
2.7.0
Resumo: Python HTTP para humanos.
Página inicial: http://python-requests.org Autor: Kenneth Reitz

E-mail do autor: me@kennethreitz.com


Licença: Apache 2.0
Localização: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages Requer:

python -m pip list exibirá todos os pacotes instalados no ambiente virtual:

(tutorial-env) $ python -m pip list novas (3.1.1.3) numpy


(1.9.2) pip (7.0.3)
requests (2.7.0)
setuptools (16.0)

python -m pip freeze produzirá uma lista semelhante dos pacotes instalados, mas a saída usa o formato que python -m pip
install espera. Uma convenção comum é colocar esta lista em um arquivo requirements.txt:

(tutorial-env) $ python -m pip freeze > requisitos.txt (tutorial-env) $ cat requisitos.txt

novas==3.1.1.3
numpy==1.9.2
pedidos==2.7.0

O requirements.txt pode então ser submetido ao controle de versão e enviado como parte de um aplicativo. Os usuários
podem então instalar todos os pacotes necessários com install -r:

(tutorial-env) $ python -m pip install -r requisitos.txt Coletando novas==3.1.1.3 (de -r requisitos.txt


(linha 1))
...
Coletando numpy==1.9.2 (de -r requirements.txt (linha 2))
...
Coletando solicitações==2.7.0 (de -r requirements.txt (linha 3))
...
Instalando pacotes coletados: novas, numpy, requests
Executando setup.py install para novas
Instalado com sucesso novas-3.1.1.3 numpy-1.9.2 requests-2.7.0

12.3. Gerenciando pacotes com pip 107


Machine Translated by Google

Tutorial do Python, versão 3.11.3

pip tem muito mais opções. Consulte o guia de instalação do índice para obter a documentação completa do pip. Quando
você escrever um pacote e quiser disponibilizá-lo no Python Package Index, consulte o guia de índice de distribuição.

108 Capítulo 12. Ambientes Virtuais e Pacotes


Machine Translated by Google

CAPÍTULO

TREZE

E AGORA?

A leitura deste tutorial provavelmente reforçou seu interesse em usar o Python — você deve estar ansioso para aplicar o Python para resolver seus
problemas do mundo real. Onde você deve ir para aprender mais?

Este tutorial faz parte do conjunto de documentação do Python. Alguns outros documentos do conjunto são:

• índice da biblioteca:

Você deve navegar por este manual, que fornece material de referência completo (embora conciso) sobre tipos, funções e módulos na biblioteca
padrão. A distribuição padrão do Python inclui muito código adicional. Existem módulos para ler caixas de correio Unix, recuperar documentos
via HTTP, gerar números aleatórios, analisar opções de linha de comando, compactar dados e muitas outras tarefas. Folhear a Referência da
Biblioteca lhe dará uma ideia do que está disponível.

• install-index explica como instalar módulos adicionais escritos por outros usuários do Python.

• index-referência: Uma explicação detalhada da sintaxe e semântica do Python. É uma leitura pesada, mas é útil como um guia completo para o
próprio idioma.

Mais recursos do Python:

• https://www.python.org: O principal site da Python. Ele contém código, documentação e ponteiros para Python
páginas relacionadas na web.

• https://docs.python.org: Acesso rápido à documentação do Python.

• https://pypi.org: O Python Package Index, anteriormente também apelidado de Cheese Shop1 , é um índice de
criou módulos Python que estão disponíveis para download. Depois de começar a liberar o código, você pode registrá-lo aqui para que outras
pessoas possam encontrá-lo.

• https://code.activestate.com/recipes/langs/python/: O Python Cookbook é uma coleção considerável de exemplos de código, módulos maiores e
scripts úteis. Contribuições particularmente notáveis são coletadas em um livro também intitulado Python Cookbook (O'Reilly & Associates,
ISBN 0-596-00797-3.)

• https://pyvideo.org coleta links para vídeos relacionados ao Python de conferências e reuniões de grupos de usuários.

• https://scipy.org: O projeto Scientific Python inclui módulos para cálculos e manipulações rápidas de matrizes, além de uma série de pacotes para
coisas como álgebra linear, transformadas de Fourier, solucionadores não lineares, distribuições de números aleatórios, análise estatística e
afins.

Para perguntas e relatórios de problemas relacionados ao Python, você pode postar no grupo de notícias comp.lang.python ou enviá-los para a lista de
discussão em python-list@python.org. O newsgroup e a lista de discussão são gatewayados, então as mensagens postadas em um serão
automaticamente encaminhadas para o outro. Há centenas de postagens por dia, fazendo (e respondendo) perguntas, sugerindo novos recursos e
anunciando novos módulos. Os arquivos da lista de discussão estão disponíveis em https://mail.python.org/ pipermail/.

Antes de postar, certifique-se de verificar a lista de Perguntas Frequentes (também chamada de FAQ). O FAQ responde a muitas das perguntas que
surgem repetidamente e pode já conter a solução para o seu problema.

1 “Cheese Shop” é um esboço de Monty Python: um cliente entra em uma loja de queijos, mas qualquer que seja o queijo que ele pede, o balconista diz que está faltando.

109
Machine Translated by Google

Tutorial do Python, versão 3.11.3

110 Capítulo 13. E agora?


Machine Translated by Google

CAPÍTULO

QUATORZE

EDIÇÃO DE ENTRADA INTERATIVA E SUBSTITUIÇÃO DE HISTÓRICO

Algumas versões do interpretador Python suportam a edição da linha de entrada atual e a substituição do histórico, semelhante aos
recursos encontrados no shell Korn e no shell GNU Bash. Isso é implementado usando o GNU Readline biblioteca, que suporta vários
estilos de edição. Esta biblioteca possui sua própria documentação que não duplicaremos aqui.

14.1 Preenchimento de guias e edição do histórico

A conclusão de nomes de variáveis e módulos é habilitada automaticamente na inicialização do interpretador para que a tecla Tab invoque
a função de conclusão; ele examina os nomes das instruções do Python, as variáveis locais atuais e os nomes dos módulos disponíveis.
Para expressões pontilhadas, como string.a, ele avaliará a expressão até o '.' final. e então sugerir complementações a partir dos
atributos do objeto resultante. Observe que isso pode executar código definido pelo aplicativo se um objeto com um método __getattr__()
fizer parte da expressão. A configuração padrão também salva seu histórico em um arquivo chamado .python_history em seu diretório de
usuário. O histórico estará disponível novamente durante a próxima sessão de intérprete interativo.

14.2 Alternativas ao Intérprete Interativo

Esta facilidade é um enorme avanço em comparação com as versões anteriores do interpretador; no entanto, alguns desejos são
deixados: Seria bom se o recuo adequado fosse sugerido nas linhas de continuação (o analisador sabe se um token de recuo é necessário
a seguir). O mecanismo de conclusão pode usar a tabela de símbolos do interpretador. Um comando para verificar (ou mesmo sugerir)
correspondência de parênteses, aspas, etc., também seria útil.

Um interpretador interativo aprimorado alternativo que já existe há algum tempo é o IPython, que apresenta preenchimento de guias,
exploração de objetos e gerenciamento avançado de histórico. Ele também pode ser totalmente personalizado e incorporado a outros
aplicativos. Outro ambiente interativo aprimorado semelhante é o bpython.

111
Machine Translated by Google

Tutorial do Python, versão 3.11.3

112 Capítulo 14. Edição de entrada interativa e substituição de histórico


Machine Translated by Google

CAPÍTULO

QUINZE

ARITMÉTICA DE PONTO FLUTUANTE: PROBLEMAS E LIMITAÇÕES

Os números de ponto flutuante são representados no hardware do computador como frações de base 2 (binárias). Por exemplo, a fração
decimal 0,125 tem valor 1/10 + 2/100 + 5/1000, e da mesma forma a fração binária 0,001 tem valor 0/2 + 0/4 + 1/8. Essas duas frações têm
valores idênticos, a única diferença real é que a primeira é escrita na notação fracionária de base 10 e a segunda na base 2.

Infelizmente, a maioria das frações decimais não pode ser representada exatamente como frações binárias. Uma consequência é que, em geral,
os números de ponto flutuante decimais que você insere são apenas aproximados pelos números de ponto flutuante binários realmente
armazenados na máquina.

O problema é mais fácil de entender a princípio na base 10. Considere a fração 1/3. Você pode aproximar isso como uma fração de base 10:

0,3

ou melhor,

0,33

ou melhor,

0,333

e assim por diante. Não importa quantos dígitos você deseja anotar, o resultado nunca será exatamente 1/3, mas será uma aproximação cada
vez melhor de 1/3.

Da mesma forma, não importa quantos dígitos de base 2 você esteja disposto a usar, o valor decimal 0,1 não pode ser representado exatamente
como uma fração de base 2. Na base 2, 1/10 é a fração infinitamente repetida

0,0001100110011001100110011001100110011001100110011...

Pare em qualquer número finito de bits e você obtém uma aproximação. Na maioria das máquinas de hoje, os floats são aproximados usando
uma fração binária com o numerador usando os primeiros 53 bits começando com o bit mais significativo e com o denominador como uma
potência de dois. No caso de 1/10, a fração binária é 3602879701896397 / 2 ** 55 que é próxima, mas não exatamente igual ao valor real de
1/10.

Muitos usuários não estão cientes da aproximação devido à forma como os valores são exibidos. Python apenas imprime uma aproximação
decimal para o valor decimal verdadeiro da aproximação binária armazenada pela máquina. Na maioria das máquinas, se o Python fosse imprimir
o valor decimal verdadeiro da aproximação binária armazenada para 0,1, ele teria que exibir

>>> 0,1
0,1000000000000000055511151231257827021181583404541015625

Isso é mais dígitos do que a maioria das pessoas acha útil, então o Python mantém o número de dígitos gerenciável exibindo um valor
arredondado.

113
Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> 1/10 _ _
0,1

Apenas lembre-se, mesmo que o resultado impresso pareça o valor exato de 1/10, o valor real armazenado é a fração binária representável
mais próxima.

Curiosamente, existem muitos números decimais diferentes que compartilham a mesma fração binária aproximada mais próxima.
Por exemplo, os números 0.1 e 0,10000000000000001 e 0.
1000000000000000055511151231257827021181583404541015625 são todos os que estão se aproximados por 3602879701896397 /2
** 55. Durante todos x)) == x.

Historicamente, o prompt do Python e a função repr() integrada escolheriam aquele com 17 dígitos significativos, 0.
10000000000000001. A partir do Python 3.1, o Python (na maioria dos sistemas) agora pode escolher o menor deles e simplesmente
exibir 0,1.

Observe que isso é da própria natureza do ponto flutuante binário: isso não é um bug no Python e também não é um bug no seu código.
Você verá o mesmo tipo de coisa em todos os idiomas que oferecem suporte à aritmética de ponto flutuante do seu hardware (embora
alguns idiomas possam não exibir a diferença por padrão ou em todos os modos de saída).

Para uma saída mais agradável, você pode usar a formatação de string para produzir um número limitado de dígitos significativos:

>>> format(math.pi, '.12g') # dá 12 dígitos significativos '3.14159265359'

>>> formato(math.pi, '.2f') # dar 2 dígitos após o ponto


'3.14'

>>> repr(math.pi)
'3.141592653589793'

É importante perceber que isso é, no sentido real, uma ilusão: você está simplesmente arredondando a exibição do verdadeiro valor da
máquina.

Uma ilusão pode gerar outra. Por exemplo, como 0,1 não é exatamente 1/10, somar três valores de 0,1 pode não resultar exatamente em
0,3:

>>> .1 + .1 + .1 == .3
Falso

Além disso, como 0,1 não pode se aproximar do valor exato de 1/10 e 0,3 não pode se aproximar do valor exato de 3/10, o pré-
arredondamento com a função round() não pode ajudar:

>>> rodada(.1, 1) + rodada(.1, 1) + rodada(.1, 1) == rodada(.3, 1)


Falso

Embora os números não possam ser aproximados de seus valores exatos pretendidos, a função round() pode ser útil para pós-
arredondamento para que os resultados com valores inexatos se tornem comparáveis entre si:

>>> rodada(.1 + .1 + .1, 10) == rodada(.3, 10)


Verdadeiro

A aritmética binária de ponto flutuante contém muitas surpresas como essa. O problema com “0,1” é explicado em detalhes precisos
abaixo, na seção “Erro de representação”. Veja os perigos do ponto flutuante para um relato mais completo de outras surpresas comuns.

Como diz perto do fim, “não há respostas fáceis”. Ainda assim, não tenha muito cuidado com o ponto flutuante! Os erros nas operações
flutuantes do Python são herdados do hardware de ponto flutuante e, na maioria das máquinas, são da ordem de não mais do que

114 Capítulo 15. Aritmética de Ponto Flutuante: Problemas e Limitações


Machine Translated by Google

Tutorial do Python, versão 3.11.3

1 parte em 2**53 por operação. Isso é mais do que adequado para a maioria das tarefas, mas você precisa ter em mente que não é
aritmética decimal e que toda operação float pode sofrer um novo erro de arredondamento.

Embora existam casos patológicos, para o uso mais casual da aritmética de ponto flutuante, você verá o resultado esperado no final se
simplesmente arredondar a exibição de seus resultados finais para o número de dígitos decimais que espera. str() geralmente é suficiente
e, para um controle mais preciso, consulte os especificadores de formato do método str.format() em formatstrings.

Para casos de uso que requerem representação decimal exata, tente usar o módulo decimal que implementa aritmética decimal adequada
para aplicativos de contabilidade e aplicativos de alta precisão.

Outra forma de aritmética exata é suportada pelo módulo de frações que implementa aritmética baseada em números racionais (para que
números como 1/3 possam ser representados com exatidão).

Se você é um usuário pesado de operações de ponto flutuante, você deve dar uma olhada no pacote NumPy e muitos outros pacotes
para operações matemáticas e estatísticas fornecidos pelo projeto SciPy. Consulte <https://scipy.org>.

O Python fornece ferramentas que podem ajudar nas raras ocasiões em que você realmente deseja saber o valor exato de um float.
O método float.as_integer_ratio() expressa o valor de um float como uma fração:

>>> x = 3,14159
>>> x.as_integer_ratio()
(3537115888337719, 1125899906842624)

Como a proporção é exata, ela pode ser usada para recriar sem perdas o valor original:

>>> x == 3537115888337719 / 1125899906842624


Verdadeiro

O método float.hex() expressa um float em hexadecimal (base 16), novamente fornecendo o valor exato armazenado pelo seu computador:

>>> x.hex()
'0x1.921f9f01b866ep+1'

Esta representação hexadecimal precisa pode ser usada para reconstruir o valor float exatamente:

>>> x == float.fromhex('0x1.921f9f01b866ep+1')
Verdadeiro

Como a representação é exata, ela é útil para portar valores de forma confiável em diferentes versões do Python (independência de
plataforma) e trocar dados com outras linguagens que suportam o mesmo formato (como Java e C99).

Outra ferramenta útil é a função math.fsum() que ajuda a reduzir a perda de precisão durante a soma. Ele rastreia “dígitos perdidos” à
medida que os valores são adicionados a um total corrente. Isso pode fazer diferença na precisão geral para que os erros não se
acumulem a ponto de afetar o total final:

>>> soma([0,1] * 10) == 1,0 Falso

>>> math.fsum([0.1] * 10) == 1.0


Verdadeiro

115
Machine Translated by Google

Tutorial do Python, versão 3.11.3

15.1 Erro de Representação

Esta seção explica o exemplo “0,1” em detalhes e mostra como você mesmo pode realizar uma análise exata de casos como este. Presume-
se familiaridade básica com a representação binária de ponto flutuante.

O erro de representação refere-se ao fato de que algumas (a maioria, na verdade) frações decimais não podem ser representadas
exatamente como frações binárias (base 2). Esta é a principal razão pela qual Python (ou Perl, C, C++, Java, Fortran e muitos outros)
muitas vezes não exibe o número decimal exato que você espera.

Por que é que? 1/10 não é exatamente representável como uma fração binária. Quase todas as máquinas hoje (novembro de 2000) usam
aritmética de ponto flutuante IEEE-754, e quase todas as plataformas mapeiam floats Python para IEEE-754 “precisão dupla”. 754 duplos
contêm 53 bits de precisão, portanto, na entrada, o computador se esforça para converter 0,1 para a fração mais próxima possível da forma
J/2**N , onde J é um inteiro contendo exatamente 53 bits. Reescrevendo

1/10 ~= J / ( 2 **N)

como

J ~= 2**N / 10

e lembrando que J tem exatamente 53 bits (é >= 2**52 mas < 2**53), o melhor valor para N é 56:

>>> 2**52 <= 2**56 // 10 < 2**53


Verdadeiro

Ou seja, 56 é o único valor para N que deixa J com exatamente 53 bits. O melhor valor possível para J é então aquele quociente
arredondado:

>>> q, r = divmod(2**56, 10)


>>> r
6

Como o resto é mais da metade de 10, a melhor aproximação é obtida arredondando para cima:

>>> q+1
7205759403792794

Portanto, a melhor aproximação possível para 1/10 em 754 precisão dupla é:

7205759403792794 / 2 ** 56

A divisão do numerador e do denominador por dois reduz a fração a:

3602879701896397 / 2 ** 55

Observe que, como arredondamos, isso é um pouco maior que 1/10; se não tivéssemos arredondado, o quociente teria sido um pouco
menor que 1/10. Mas em nenhum caso pode ser exatamente 1/10!

Portanto, o computador nunca “vê” 1/10: o que ele vê é a fração exata fornecida acima, a melhor aproximação dupla de 754 que pode obter:

>>> 0,1 * 2 ** 55
3602879701896397.0

Se multiplicarmos essa fração por 10 ** 55, podemos ver o valor até 55 dígitos decimais:

116 Capítulo 15. Aritmética de Ponto Flutuante: Problemas e Limitações


Machine Translated by Google

Tutorial do Python, versão 3.11.3

>>> 3602879701896397 * 10 ** 55 // 2 ** 55
1000000000000000055511151231257827021181583404541015625

significando que o número exato armazenado no computador é igual ao valor decimal


0,10000000000000000555111151231257827021181583404541015625. Em vez de exibir o valor decimal
completo, muitos idiomas (incluindo versões mais antigas do Python) arredondam o resultado para 17 dígitos significativos:

>>> format(0.1, '.17f')


'0.10000000000000001'

As frações e os módulos decimais facilitam esses cálculos:

>>> de importação decimal Decimal >>> de


importação de frações Fração

>>> Fraction.from_float(0.1)
Fração (3602879701896397, 36028797018963968)

>>> (0.1).as_integer_ratio() (3602879701896397,


36028797018963968)

>>> Decimal.from_float(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')

>>> format(Decimal.from_float(0.1), '.17') '0.100000000000000001'

15.1. Erro de representação 117


Machine Translated by Google

Tutorial do Python, versão 3.11.3

118 Capítulo 15. Aritmética de Ponto Flutuante: Problemas e Limitações


Machine Translated by Google

CAPÍTULO

DEZESSEIS

APÊNDICE

16.1 Modo interativo

16.1.1 Tratamento de Erros

Quando ocorre um erro, o interpretador imprime uma mensagem de erro e um rastreamento de pilha. No modo interativo, ele retorna ao
prompt principal; quando a entrada vem de um arquivo, ela sai com um status de saída diferente de zero após imprimir o rastreamento de
pilha. (Exceções tratadas por uma cláusula except em uma instrução try não são erros neste contexto.) Alguns erros são incondicionalmente
fatais e causam uma saída com uma saída diferente de zero; isso se aplica a inconsistências internas e alguns casos de falta de memória.
Todas as mensagens de erro são gravadas no fluxo de erro padrão; a saída normal dos comandos executados é gravada na saída padrão.

Digitar o caractere de interrupção (geralmente Control-C ou Delete) no prompt primário ou secundário cancela a entrada e retorna ao
prompt primário.1 Digitar uma interrupção durante a execução de um comando gera a exceção KeyboardInterrupt, que pode ser tratada
por uma instrução try .

16.1.2 Scripts Python executáveis

Em sistemas BSD'ish Unix, os scripts Python podem ser executados diretamente, como scripts shell, colocando a linha

#!/usr/bin/env python3.5

(supondo que o interpretador esteja no PATH do usuário) no início do script e dando ao arquivo um modo executável.
O #! devem ser os dois primeiros caracteres do arquivo. Em algumas plataformas, essa primeira linha deve terminar com um final de linha
no estilo Unix ('\n'), não com um final de linha do Windows ('\r\n'). Observe que o caractere hash, ou libra, '#', é usado para iniciar um
comentário em Python.

O script pode receber um modo executável, ou permissão, usando o comando chmod .

$ chmod +x meuscript.py

Em sistemas Windows, não há noção de “modo executável”. O instalador do Python associa automaticamente arquivos .py com python.exe
para que um clique duplo em um arquivo Python o execute como um script. A extensão também pode ser .pyw, nesse caso, a janela do
console que normalmente aparece é suprimida.
1 Um problema com o pacote GNU Readline pode impedir isso.

119
Machine Translated by Google

Tutorial do Python, versão 3.11.3

16.1.3 O arquivo de inicialização interativo

Quando você usa o Python interativamente, geralmente é útil ter alguns comandos padrão executados toda vez que o interpretador é iniciado.
Você pode fazer isso definindo uma variável de ambiente chamada PYTHONSTARTUP para o nome de um arquivo contendo seus comandos
de inicialização. Isso é semelhante ao recurso .profile dos shells Unix.

Este arquivo é lido apenas em sessões interativas, não quando o Python lê comandos de um script e não quando /dev/tty é fornecido como a
fonte explícita de comandos (que, de outra forma, se comporta como uma sessão interativa). Ele é executado no mesmo namespace onde os
comandos interativos são executados, para que os objetos que ele define ou importa possam ser usados sem qualificação na sessão interativa.
Você também pode alterar os prompts sys.ps1 e sys.ps2 neste arquivo.

Se você deseja ler um arquivo de inicialização adicional do diretório atual, pode programá-lo no arquivo de inicialização global usando um
código como if os.path.isfile('.pythonrc.py'): exec(open(' .pythonrc.py').read()).
Se você deseja usar o arquivo de inicialização em um script, deve fazer isso explicitamente no script:

import os
filename = os.environ.get('PYTHONSTARTUP') if filename e
os.path.isfile(filename):
com open(filename) como fobj:
startup_file = fobj.read() exec(startup_file)

16.1.4 Os Módulos de Customização

O Python fornece dois ganchos para permitir que você o personalize: sitecustomize e usercustomize. Para ver como funciona, você precisa
primeiro encontrar a localização do diretório de pacotes do site do usuário. Inicie o Python e execute este código:

>>> importar site >>>


site.getusersitepackages() '/home/user/.local/
lib/python3.5/site-packages'

Agora você pode criar um arquivo chamado usercustomize.py nesse diretório e colocar o que quiser nele. Isso afetará todas as chamadas do
Python, a menos que seja iniciado com a opção -s para desativar a importação automática.

sitecustomize funciona da mesma maneira, mas normalmente é criado por um administrador do computador no diretório global de pacotes de
sites e é importado antes de usercustomize. Consulte a documentação do módulo site para obter mais detalhes.

120 Capítulo 16. Apêndice


Machine Translated by Google

APÊNDICE

GLOSSÁRIO

>>> O prompt Python padrão do shell interativo. Frequentemente visto para exemplos de código que podem ser executados interativamente
no intérprete.

... Pode referir-se a:

• O prompt Python padrão do shell interativo ao inserir o código para um bloco de código recuado, quando dentro de um par de
delimitadores esquerdo e direito correspondentes (parênteses, colchetes, chaves ou aspas triplas) ou depois de especificar um
decorador.

• A constante interna de reticências.

2to3 Uma ferramenta que tenta converter o código Python 2.x para o código Python 3.x lidando com a maioria das incompatibilidades que podem
ser detectado analisando a fonte e percorrendo a árvore de análise.

2to3 está disponível na biblioteca padrão como lib2to3; um ponto de entrada autônomo é fornecido como Tools/scripts/ 2to3. Consulte a
referência 2to3.

classe base abstrata Classes base abstratas complementam a digitação de patos fornecendo uma maneira de definir interfaces quando outras
técnicas como hasattr() seriam desajeitadas ou sutilmente erradas (por exemplo, com métodos mágicos). ABCs introduzem subclasses
virtuais, que são classes que não herdam de uma classe, mas ainda são reconhecidas por isinstance() e issubclass(); consulte a
documentação do módulo abc. O Python vem com muitos ABCs integrados para estruturas de dados (no módulo collections.abc), números
(no módulo de números), fluxos (no módulo io), localizadores e carregadores de importação (no módulo importlib.abc). Você pode criar seus
próprios ABCs com o módulo abc.

anotação Um rótulo associado a uma variável, um atributo de classe ou um parâmetro de função ou valor de retorno, usado por convenção
como uma dica de tipo.

Anotações de variáveis locais não podem ser acessadas em tempo de execução, mas anotações de variáveis globais, atributos de classe e
funções são armazenadas no atributo especial __annotations__ de módulos, classes e funções, respectivamente.

Consulte anotação de variável, anotação de função, PEP 484 e PEP 526, que descrevem esta funcionalidade. Consulte também o tutorial
de anotações para obter as melhores práticas para trabalhar com anotações.

argumento Um valor passado para uma função (ou método) ao chamar a função. Existem dois tipos de argumento:

• argumento de palavra-chave: um argumento precedido por um identificador (por exemplo, name=) em uma chamada de função ou
passado como um valor em um dicionário precedido por **. Por exemplo, 3 e 5 são argumentos de palavra-chave nas seguintes
chamadas para complex():

complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5})

• argumento posicional: um argumento que não é um argumento de palavra-chave. Os argumentos posicionais podem aparecer no início
de uma lista de argumentos e/ou ser passados como elementos de um iterável precedido por *. Por exemplo, 3 e 5 são argumentos
posicionais nas seguintes chamadas:

121
Machine Translated by Google

Tutorial do Python, versão 3.11.3

complexo(3, 5)
complexo(*(3, 5))

Os argumentos são atribuídos às variáveis locais nomeadas em um corpo de função. Consulte a seção de chamadas para as regras que
regem esta atribuição. Sintaticamente, qualquer expressão pode ser usada para representar um argumento; o valor avaliado é atribuído à
variável local.

Consulte também a entrada do glossário de parâmetros , a pergunta do FAQ sobre a diferença entre argumentos e parâmetros e PEP 362.

gerenciador de contexto assíncrono Um objeto que controla o ambiente visto em uma instrução assíncrona com a definição dos métodos
__aenter__() e __aexit__(). Introduzido por PEP 492.

gerador assíncrono Uma função que retorna um iterador gerador assíncrono. Parece uma função de co-rotina definida com async def, exceto
que contém expressões yield para produzir uma série de valores utilizáveis em um loop for assíncrono.

Geralmente se refere a uma função de gerador assíncrono, mas pode se referir a um iterador de gerador assíncrono em alguns contextos.
Nos casos em que o significado pretendido não é claro, usar os termos completos evita ambigüidades.

Uma função geradora assíncrona pode conter expressões await, bem como instruções async for e async with.

iterador gerador assíncrono Um objeto criado por uma função geradora assíncrona .

Este é um iterador assíncrono que quando chamado usando o método __anext__() retorna um objeto awaitable que executará o corpo da
função geradora assíncrona até a próxima expressão yield.

Cada yield suspende temporariamente o processamento, lembrando o estado de execução do local (incluindo variáveis locais e instruções
try pendentes). Quando o iterador do gerador assíncrono efetivamente retoma com outro awaitable retornado por __anext__(), ele continua
de onde parou. Consulte PEP 492 e PEP 525.

iterável assíncrono Um objeto que pode ser usado em uma instrução for assíncrona. Deve retornar um iterador assíncrono
de seu método __aiter__(). Introduzido por PEP 492.

iterador assíncrono Um objeto que implementa os métodos __aiter__() e __anext__(). __anext__ deve retornar um objeto aguardável . async
para resolve os awaitables retornados pelo método __anext__() de um iterador assíncrono até gerar uma exceção StopAsyncIteration.
Introduzido por PEP 492.

atributo Um valor associado a um objeto que geralmente é referenciado pelo nome usando expressões pontilhadas. Por exemplo,
se um objeto o tiver um atributo a, ele será referenciado como oa

É possível atribuir a um objeto um atributo cujo nome não seja um identificador conforme definido pelos identificadores, por exemplo,
usando setattr(), se o objeto permitir. Esse atributo não será acessível usando uma expressão pontilhada e, em vez disso, precisaria ser
recuperado com getattr().

awaitable Um objeto que pode ser usado em uma expressão await. Pode ser uma co-rotina ou um objeto com __await__()
método. Veja também PEP 492.

BDFL Benevolent Dictator For Life, também conhecido como Guido van Rossum, criador do Python.

arquivo binário Um objeto de arquivo capaz de ler e gravar objetos semelhantes a bytes. Exemplos de arquivos binários são arquivos abertos em
modo binário ('rb', 'wb' ou 'rb+'), sys.stdin.buffer, sys.stdout.buffer e instâncias de io.BytesIO e gzip.GzipFile.

Consulte também arquivo de texto para um objeto de arquivo capaz de ler e gravar objetos str.

referência emprestada Na API C do Python, uma referência emprestada é uma referência a um objeto. Ele não modifica a contagem de referência
do objeto. Torna-se um ponteiro pendurado se o objeto for destruído. Por exemplo, uma coleta de lixo pode remover a última referência
forte ao objeto e assim destruí-lo.

122 Apêndice A. Glossário


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Chamar Py_INCREF() na referência emprestada é recomendado para convertê-la em uma referência forte no local, exceto quando o objeto
não pode ser destruído antes do último uso da referência emprestada. A função Py_NewRef() pode ser usada para criar uma nova
referência forte.

objeto semelhante a bytes Um objeto que suporta bufferobjects e pode exportar um buffer C-contíguo . Isso inclui todos os objetos bytes,
bytearray e array.array, bem como muitos objetos comuns de memoryview. Objetos semelhantes a bytes podem ser usados para várias
operações que funcionam com dados binários; isso inclui compactação, salvamento em um arquivo binário e envio por um soquete.

Algumas operações precisam que os dados binários sejam mutáveis. A documentação geralmente se refere a eles como “bytes de leitura
e gravação como objetos”. Exemplos de objetos de buffer mutável incluem bytearray e uma memoryview de um bytearray. Outras operações
requerem que os dados binários sejam armazenados em objetos imutáveis (“objetos semelhantes a bytes somente leitura”); exemplos
disso incluem bytes e um memoryview de um objeto de bytes.

bytecode O código-fonte Python é compilado em bytecode, a representação interna de um programa Python no interpretador CPython. O bytecode
também é armazenado em cache em arquivos .pyc para que a execução do mesmo arquivo seja mais rápida na segunda vez (a
recompilação da fonte para o bytecode pode ser evitada). Diz-se que essa “linguagem intermediária” é executada em uma máquina virtual
que executa o código de máquina correspondente a cada bytecode. Observe que não se espera que os bytecodes funcionem entre
diferentes máquinas virtuais do Python, nem sejam estáveis entre as versões do Python.

Uma lista de instruções de bytecode pode ser encontrada na documentação do módulo dis.

callable Um callable é um objeto que pode ser chamado, possivelmente com um conjunto de argumentos (ver argumento), com o seguinte
sintaxe:

callable(argumento1, argumento2, argumentoN)

Uma função e, por extensão, um método, é um callable. Uma instância de uma classe que implementa o método __call__() também é um
callable.

retorno de chamada Uma função de sub-rotina que é passada como um argumento a ser executado em algum momento no futuro.

classe Um modelo para criar objetos definidos pelo usuário. As definições de classe normalmente contêm definições de método que operam em
instâncias da classe.

variável de classe Uma variável definida em uma classe e destinada a ser modificada apenas no nível de classe (ou seja, não em uma instância do
aula).

número complexo Uma extensão do familiar sistema de números reais em que todos os números são expressos como uma soma de uma parte
real e uma parte imaginária. Números imaginários são múltiplos reais da unidade imaginária (a raiz quadrada de -1), muitas vezes escritos
i em matemática ou j em engenharia. Python tem suporte interno para números complexos, que são escritos com esta última notação; a
parte imaginária é escrita com o sufixo aj, por exemplo, 3+1j. Para obter acesso a equivalentes complexos do módulo math, use cmath. O
uso de números complexos é um recurso matemático bastante avançado.
Se você não está ciente da necessidade deles, é quase certo que você pode ignorá-los com segurança.

gerenciador de contexto Um objeto que controla o ambiente visto em uma instrução with definindo __enter__() e
Métodos __exit__(). Veja PEP 343.

variável de contexto Uma variável que pode ter valores diferentes dependendo de seu contexto. Isso é semelhante ao Thread-Local Storage, no
qual cada thread de execução pode ter um valor diferente para uma variável. No entanto, com variáveis de contexto, pode haver vários
contextos em um encadeamento de execução e o uso principal para variáveis de contexto é acompanhar as variáveis em tarefas
assíncronas simultâneas. Veja contextvars.

contíguo Um buffer é considerado contíguo exatamente se for C-contíguo ou Fortran contíguo. Os buffers de dimensão zero são C e Fortran
contíguos. Em arrays unidimensionais, os itens devem ser dispostos na memória um ao lado do outro, em ordem crescente de índices a
partir de zero. Em arrays C-contíguos multidimensionais, o último índice varia mais rapidamente ao visitar itens em ordem de endereço de
memória. No entanto, em arrays contíguos Fortran, o primeiro índice varia mais rapidamente.

123
Machine Translated by Google

Tutorial do Python, versão 3.11.3

co-rotina Cor-rotinas são uma forma mais generalizada de sub-rotinas. As sub-rotinas são inseridas em um ponto e encerradas em outro ponto.
As corrotinas podem ser inseridas, encerradas e retomadas em muitos pontos diferentes. Eles podem ser implementados com a instrução
def async. Veja também PEP 492.

função co-rotina Uma função que retorna um objeto co-rotina . Uma função de co-rotina pode ser definida com a instrução async def e pode
conter await, async for e async with palavras-chave. Estes foram introduzidos pelo PEP 492.

CPython A implementação canônica da linguagem de programação Python, distribuída em python.org. O termo “CPython” é usado quando
necessário para distinguir esta implementação de outras como Jython ou IronPython.

decorator Uma função que retorna outra função, geralmente aplicada como uma transformação de função usando a sintaxe @wrapper. Exemplos
comuns de decoradores são classmethod() e staticmethod().

A sintaxe do decorador é meramente um açúcar sintático, as duas definições de função a seguir são semanticamente equivalentes:

def f(arg):
...
f = método estático(f)

@staticmethod def
f(arg):
...

O mesmo conceito existe para classes, mas é menos comumente usado lá. Consulte a documentação para definições de função e
definições de classe para saber mais sobre decoradores.

descritor Qualquer objeto que define os métodos __get__(), __set__() ou __delete__(). Quando um atributo de classe é um descritor, seu
comportamento de ligação especial é acionado na pesquisa de atributo. Normalmente, usar ab para obter, definir ou excluir um atributo
procura o objeto chamado b no dicionário de classes para a, mas se b for um descritor, o respectivo método descritor será chamado.
Compreender os descritores é a chave para uma compreensão profunda do Python porque eles são a base para muitos recursos, incluindo
funções, métodos, propriedades, métodos de classe, métodos estáticos e referência a superclasses.

Para obter mais informações sobre os métodos dos descritores, consulte descritores ou o Guia de instruções do descritor.

dicionário Um array associativo, onde chaves arbitrárias são mapeadas para valores. As chaves podem ser qualquer objeto com
Métodos __hash__() e __eq__(). Chamado de hash em Perl.

compreensão do dicionário Uma maneira compacta de processar todos ou parte dos elementos em um iterável e retornar um dicionário ** 2 para
com os resultados. resultados = {n: n chave n n no intervalo(10)} gera um dicionário contendo
mapeada para o valor n ** 2. Ver compreensões.

visualização de dicionário Os objetos retornados de dict.keys(), dict.values() e dict.items() são chamados de visualizações de dicionário. Eles
fornecem uma visão dinâmica das entradas do dicionário, o que significa que quando o dicionário muda, a visão reflete essas mudanças.
Para forçar a visualização do dicionário a se tornar uma lista completa, use list(dictview).
Veja dict-views.

docstring Uma string literal que aparece como a primeira expressão em uma classe, função ou módulo. Embora ignorado quando o conjunto é
executado, ele é reconhecido pelo compilador e colocado no atributo __doc__ da classe, função ou módulo envolvente. Uma vez que está
disponível via introspecção, é o lugar canônico para a documentação do objeto.

duck-typing Um estilo de programação que não olha para o tipo de um objeto para determinar se ele tem a interface correta; em vez disso, o
método ou atributo é simplesmente chamado ou usado (“Se parece um pato e grasna como um pato, deve ser um pato.”) Ao enfatizar
interfaces em vez de tipos específicos, um código bem projetado melhora sua flexibilidade permitindo substituição polimórfica. Duck-typing
evita testes usando type() ou isinstance(). (Observe, no entanto, que a digitação de pato pode ser complementada com classes base
abstratas.) Em vez disso, ela normalmente emprega testes hasattr() ou programação EAFP .

EAFP Mais fácil pedir perdão do que permissão. Esse estilo de codificação Python comum assume a existência de chaves ou atributos válidos e
captura exceções se a suposição for falsa. Este estilo limpo e rápido é caracterizado

124 Apêndice A. Glossário


Machine Translated by Google

Tutorial do Python, versão 3.11.3

pela presença de muitos try e except declarações. A técnica contrasta com o estilo LBYL comum a muitas outras linguagens, como C.

expressão Uma parte da sintaxe que pode ser avaliada para algum valor. Em outras palavras, uma expressão é um acúmulo de elementos de
expressão como literais, nomes, acesso a atributos, operadores ou chamadas de função que retornam um valor.
Em contraste com muitas outras linguagens, nem todas as construções de linguagem são expressões. Existem também declarações que
não podem ser usadas como expressões, como while. Atribuições também são instruções, não expressões.

módulo de extensão Um módulo escrito em C ou C++, usando a API C do Python para interagir com o núcleo e com o código do usuário.

f-string Literais de string prefixados com 'f' ou 'F' são comumente chamados de “f-strings”, que é a abreviação de string formatada
literais. Veja também PEP 498.

objeto de arquivo Um objeto que expõe uma API orientada a arquivo (com métodos como read() ou write()) a um recurso subjacente. Dependendo
da forma como foi criado, um objeto de arquivo pode mediar o acesso a um arquivo real em disco ou a outro tipo de armazenamento ou
dispositivo de comunicação (por exemplo, entrada/saída padrão, buffers de memória, soquetes, pipes, etc.) . Os objetos de arquivo também
são chamados de fluxos ou objetos semelhantes a arquivos .

Na verdade, existem três categorias de objetos de arquivo: arquivos binários brutos, arquivos binários em buffer e arquivos de texto. Suas
interfaces são definidas no módulo io. A maneira canônica de criar um objeto de arquivo é usando a função open().

objeto semelhante a arquivo Um sinônimo para objeto de arquivo.

codificação do sistema de arquivos e manipulador de erros Codificação e manipulador de erros usados pelo Python para decodificar bytes do
sistema operacional e codificar Unicode para o sistema operacional.

A codificação do sistema de arquivos deve garantir a decodificação bem-sucedida de todos os bytes abaixo de 128. Se a codificação do
sistema de arquivos não fornecer essa garantia, as funções da API podem gerar UnicodeError.

As funções sys.getfilesystemencoding() e sys.getfilesystemencodeerrors() podem ser usadas para obter a codificação do sistema de
arquivos e o manipulador de erros.

A codificação do sistema de arquivos e o manipulador de erros são configurados na inicialização do Python pela função PyConfig_Read():
consulte os membros filesystem_encoding e filesystem_errors do PyConfig.

Consulte também a codificação de localidade.

localizador Um objeto que tenta localizar o carregador para um módulo que está sendo importado.

Desde o Python 3.3, há dois tipos de localizador: localizadores de caminho meta para uso com sys.meta_path e localizadores de entrada de
caminho para uso com sys.path_hooks.

Consulte PEP 302, PEP 420 e PEP 451 para muito mais detalhes.

divisão de piso Divisão matemática que arredonda para o número inteiro mais próximo. O operador de divisão do piso é //. Por exemplo, a
expressão 11 // 4 é avaliada como 2 em contraste com 2,75 retornado por float true division. Observe que (-11) // 4 é -3 porque é -2,75
arredondado para baixo. Veja PEP 238.

função Uma série de instruções que retorna algum valor para um chamador. Também pode ser passado zero ou mais argumentos que podem ser
usados na execução do corpo. Consulte também parâmetro, método e a seção de função.

anotação de função Uma anotação de um parâmetro de função ou valor de retorno.

Anotações de função são geralmente usadas para dicas de tipo: por exemplo, espera-se que esta função receba dois argumentos int e
também tenha um valor de retorno int:

def sum_two_numbers(a: int, b: int) -> int:


retornar a + b

A sintaxe de anotação de função é explicada na seção função.

Ver anotação variável e PEP 484, que descrevem esta funcionalidade. Consulte também o tutorial de anotações para obter as melhores
práticas para trabalhar com anotações.

125
Machine Translated by Google

Tutorial do Python, versão 3.11.3

__future__ Uma declaração futura, de __future__ import <recurso>, direciona o compilador para compilar o módulo atual usando sintaxe ou
semântica que se tornará padrão em uma versão futura do Python. O módulo __future__ documenta os valores possíveis do recurso. Ao
importar este módulo e avaliar suas variáveis, você pode ver quando um novo recurso foi adicionado pela primeira vez ao idioma e quando
ele se tornará (ou se tornou) o padrão:

>>> importar __future__ >>>


__future__.division
_Feature((2, 2, 0, 'alfa', 2), (3, 0, 0, 'alfa', 0), 8192)

coleta de lixo O processo de liberar memória quando ela não é mais usada. O Python executa a coleta de lixo por meio de contagem de referência
e um coletor de lixo cíclico capaz de detectar e quebrar ciclos de referência. O coletor de lixo pode ser controlado usando o módulo gc.

gerador Uma função que retorna um gerador iterador. Parece uma função normal, exceto pelo fato de conter expressões yield para produzir uma
série de valores utilizáveis em um loop for ou que podem ser recuperados um de cada vez com a função next().

Geralmente se refere a uma função geradora, mas pode se referir a um iterador gerador em alguns contextos. Nos casos em que o
significado pretendido não é claro, usar os termos completos evita ambigüidades.

gerador iterador Um objeto criado por uma função geradora .

Cada yield suspende temporariamente o processamento, lembrando o estado de execução do local (incluindo variáveis locais e instruções
try pendentes). Quando o iterador do gerador recomeça, ele continua de onde parou (em contraste com as funções que começam do zero
a cada chamada).

expressão do gerador Uma expressão que retorna um iterador. Parece uma expressão normal seguida por uma cláusula for definindo uma variável
de loop, intervalo e uma cláusula if opcional. A expressão combinada gera valores para uma função de fechamento:

>>> soma(i*i para i no intervalo(10)) 285 # soma dos quadrados 0, 1, 4, ... 81

função genérica Uma função composta de múltiplas funções implementando a mesma operação para diferentes tipos. Qual implementação deve
ser usada durante uma chamada é determinada pelo algoritmo de despacho.

Consulte também a entrada do glossário de despacho único , o decorador functools.singledispatch() e PEP 443.

tipo genérico Um tipo que pode ser parametrizado; normalmente uma classe de contêiner, como list ou dict. Usado para dicas de tipo
e anotações.

Para obter mais detalhes, consulte tipos de alias genéricos, PEP 483, PEP 484, PEP 585, e o módulo de digitação.

GIL Consulte bloqueio de intérprete global.

global interpreter lock O mecanismo usado pelo interpretador CPython para garantir que apenas um thread execute o bytecode Python por vez.
Isso simplifica a implementação do CPython tornando o modelo de objeto (incluindo tipos integrados críticos, como dict) implicitamente
seguro contra acesso simultâneo. Bloquear todo o interpretador torna mais fácil para o interpretador ser multiencadeado, às custas de muito
do paralelismo oferecido por máquinas multiprocessadas.

No entanto, alguns módulos de extensão, padrão ou de terceiros, são projetados para liberar o GIL ao realizar tarefas computacionais
intensivas, como compactação ou hash. Além disso, o GIL é sempre liberado ao fazer I/O.

Esforços anteriores para criar um interpretador “free-threaded” (um que bloqueie dados compartilhados em uma granularidade muito mais
fina) não foram bem-sucedidos porque o desempenho foi prejudicado no caso comum de processador único. Acredita-se que superar esse
problema de desempenho tornaria a implementação muito mais complicada e, portanto, mais cara de manter.

pyc baseado em hash Um arquivo de cache de bytecode que usa o hash em vez da hora da última modificação do arquivo de origem
correspondente para determinar sua validade. Consulte invalidação de pyc.

126 Apêndice A. Glossário


Machine Translated by Google

Tutorial do Python, versão 3.11.3

hashable Um objeto é hashable se ele tem um valor de hash que nunca muda durante seu tempo de vida (ele precisa de um método __hash__())
e pode ser comparado a outros objetos (ele precisa de um método __eq__()). Objetos hasháveis que comparam iguais devem ter o mesmo
valor de hash.

A capacidade de hash torna um objeto utilizável como uma chave de dicionário e um membro de conjunto, porque essas estruturas de dados usam o valor
de hash internamente.

A maioria dos objetos internos imutáveis do Python são passíveis de hash; contêineres mutáveis (como listas ou dicionários) não são;
contêineres imutáveis (como tuplas e frozensets) só são hasháveis se seus elementos forem hasháveis. Objetos que são instâncias de
classes definidas pelo usuário são passíveis de hash por padrão. Todos eles comparam desigual (exceto com eles mesmos), e seu valor de
hash é derivado de seu id ().

IDLE Um ambiente integrado de desenvolvimento e aprendizado para Python. idle é um ambiente básico de edição e interpretação
mento que acompanha a distribuição padrão do Python.

imutável Um objeto com um valor fixo. Objetos imutáveis incluem números, strings e tuplas. Tal objeto não pode ser alterado. Um novo objeto deve
ser criado se um valor diferente tiver que ser armazenado. Eles desempenham um papel importante em locais onde um valor de hash
constante é necessário, por exemplo, como uma chave em um dicionário.

caminho de importação Uma lista de locais (ou entradas de caminho) que são pesquisados pelo localizador baseado em caminho para módulos a
serem importados. Durante a importação, essa lista de locais geralmente vem de sys.path, mas para subpacotes também pode vir do atributo
__path__ do pacote pai.

importando O processo pelo qual o código Python em um módulo é disponibilizado para o código Python em outro módulo.

importador Um objeto que localiza e carrega um módulo; um objeto localizador e carregador .

Python interativo tem um interpretador interativo, o que significa que você pode inserir instruções e expressões no prompt do interpretador, executá-
los imediatamente e ver seus resultados. Basta iniciar o python sem argumentos (possivelmente selecionando-o no menu principal do seu
computador). É uma maneira muito poderosa de testar novas ideias ou inspecionar módulos e pacotes (lembre-se de help(x)).

Python interpretado é uma linguagem interpretada, em oposição a uma linguagem compilada, embora a distinção possa ser confusa devido à
presença do compilador de bytecode. Isso significa que os arquivos de origem podem ser executados diretamente sem criar explicitamente
um executável que é executado. As linguagens interpretadas normalmente têm um ciclo de desenvolvimento/depuração mais curto do que
as compiladas, embora seus programas geralmente também sejam executados mais lentamente. Veja também interativo.

desligamento do interpretador Quando solicitado a desligar, o interpretador Python entra em uma fase especial onde libera gradualmente todos os
recursos alocados, como módulos e várias estruturas internas críticas. Ele também faz várias chamadas para o coletor de lixo. Isso pode
acionar a execução de código em destruidores definidos pelo usuário ou retornos de chamada de referência fraca. O código executado
durante a fase de desligamento pode encontrar várias exceções, pois os recursos dos quais ele depende podem não funcionar mais
(exemplos comuns são módulos de biblioteca ou máquinas de avisos).

A principal razão para o encerramento do interpretador é que o módulo __main__ ou o script que está sendo executado terminou de executar.

iterável Um objeto capaz de retornar seus membros um de cada vez. Exemplos de iteráveis incluem todos os tipos de sequência (como lista, str e
tupla) e alguns tipos não sequenciais como dict, objetos de arquivo e objetos de qualquer classe definida com um método __iter__() ou com
um método __getitem__() que implementa semântica de sequência .

Iterables podem ser usados em um loop for e em muitos outros lugares onde uma sequência é necessária (zip(), map(), …).
Quando um objeto iterável é passado como um argumento para a função integrada iter(), ele retorna um iterador para o objeto. Este iterador
é bom para uma passagem sobre o conjunto de valores. Ao usar iteráveis, geralmente não é necessário chamar iter() ou lidar com objetos
iteradores você mesmo. A instrução for faz isso automaticamente para você, criando uma variável temporária sem nome para manter o
iterador durante o loop. Consulte também iterador, sequência e gerador.

iterador Um objeto que representa um fluxo de dados. Chamadas repetidas para o método __next__() do iterador (ou passando-o para a função
interna next()) retornam itens sucessivos no fluxo. Quando não há mais dados disponíveis, uma exceção StopIteration é lançada. Neste
ponto, o objeto do iterador está esgotado e quaisquer chamadas adicionais para seu método __next__() apenas levantam StopIteration
novamente. Iteradores são obrigados a ter um __iter__()

127
Machine Translated by Google

Tutorial do Python, versão 3.11.3

método que retorna o próprio objeto iterador para que cada iterador também seja iterável e possa ser usado na maioria dos locais onde outros
iteráveis são aceitos. Uma exceção notável é o código que tenta várias passagens de iteração. Um objeto contêiner (como uma lista) produz um
novo iterador toda vez que você o passa para a função iter() ou o usa em um loop for. Tentar fazer isso com um iterador apenas retornará o
mesmo objeto iterador esgotado usado na passagem de iteração anterior, fazendo com que pareça um contêiner vazio.

Mais informações podem ser encontradas em typeiter.

Detalhe da implementação do CPython: o CPython não aplica consistentemente o requisito de que um iterador defina __iter__().

função-chave Uma função-chave ou função de collation é um callable que retorna um valor usado para classificar ou ordenar. Por exemplo, locale.strxfrm()
é usado para produzir uma chave de classificação que esteja ciente das convenções de classificação específicas do local.

Várias ferramentas em Python aceitam funções-chave para controlar como os elementos são ordenados ou agrupados. Eles incluem min(),
max(), sorted(), list.sort(), heapq.merge(), heapq.nsmallest(), heapq. nlargest() e itertools.groupby().

Existem várias maneiras de criar uma função chave. Por exemplo. o método str.lower() pode servir como uma função chave para classificações
que não diferenciam maiúsculas de minúsculas. Alternativamente, uma função chave pode ser criada a partir de uma expressão lambda, como
lambda r: (r[0], r[2]). Além disso, operator.attrgetter(), operator.itemgetter() e operator.methodcaller() são três construtores de função chave.
Consulte Sorting HOW TO para exemplos de como criar e usar funções-chave.

argumento de palavra-chave Veja argumento.

lambda Uma função inline anônima que consiste em uma única expressão que é avaliada quando a função é chamada.
A sintaxe para criar uma função lambda é lambda [parâmetros]: expressão

LBYL Olhe antes de pular. Esse estilo de codificação testa explicitamente as pré-condições antes de fazer chamadas ou pesquisas. Este estilo contrasta
com a abordagem EAFP e é caracterizado pela presença de muitas instruções if.

Em um ambiente multi-threaded, a abordagem LBYL pode arriscar a introdução de uma condição de corrida entre “o olhar” e “o salto”. Por
exemplo, o código if key in mapping: return mapping[key] pode falhar se outro thread remover a chave do mapeamento após o teste, mas antes
da pesquisa. Esse problema pode ser resolvido com bloqueios ou usando a abordagem EAFP.

codificação de localidade No Unix, é a codificação da localidade LC_CTYPE. setlocale(locale.LC_CTYPE, Pode ser definido com localidade.
new_locale).

No Windows, é a página de código ANSI (ex: "cp1252").

No Android e no VxWorks, o Python usa "utf-8" como codificação de localidade.

locale.getencoding() pode ser usado para obter a codificação de localidade.

Consulte também a codificação do sistema de arquivos e o manipulador de erros.

list Uma sequência interna do Python . Apesar do nome, é mais parecido com um array em outras linguagens do que com uma lista encadeada, pois
o acesso aos elementos é O(1).

compreensão da lista Uma maneira compacta de processar todos ou parte dos elementos em uma sequência e retornar uma lista com os resultados.
result = ['{:#04x}'.format(x) for x in range(256) if x % 2 == 0] gera uma lista de strings contendo números hexadecimais pares (0x..) no intervalo
de 0 a 255. A cláusula if é opcional. Se omitido, todos os elementos em range(256) são processados.

carregador Um objeto que carrega um módulo. Ele deve definir um método chamado load_module(). Um carregador normalmente é retornado por um
localizador. Consulte PEP 302 para obter detalhes e importlib.abc.Loader para uma classe base abstrata.

método mágico Um sinônimo informal para método especial.

mapeamento Um objeto contêiner que oferece suporte a pesquisas de chave arbitrárias e implementa os métodos especificados nas classes base
abstratas collections.abc.Mapping ou collections.abc.MutableMapping.

128 Apêndice A. Glossário


Machine Translated by Google

Tutorial do Python, versão 3.11.3

Os exemplos incluem dict, collections.defaultdict, collections.OrderedDict e collections.Counter.

meta path finder Um localizador retornado por uma pesquisa de sys.meta_path. Os localizadores de caminho meta estão relacionados, mas são diferentes dos
localizadores de entrada de caminho.

Consulte importlib.abc.MetaPathFinder para obter os métodos implementados pelos localizadores de caminhos meta.

metaclasse A classe de uma classe. As definições de classe criam um nome de classe, um dicionário de classe e uma lista de classes base. A
metaclasse é responsável por pegar esses três argumentos e criar a classe. A maioria das linguagens de programação orientada a
objetos fornece uma implementação padrão. O que torna o Python especial é que é possível criar metaclasses personalizadas. A maioria
dos usuários nunca precisa dessa ferramenta, mas quando surge a necessidade, as metaclasses podem fornecer soluções poderosas e
elegantes. Eles têm sido usados para registrar o acesso a atributos, adicionar thread-safety, rastrear a criação de objetos, implementar
singletons e muitas outras tarefas.

Mais informações podem ser encontradas em metaclasses.

método Uma função que é definida dentro do corpo de uma classe. Se chamado como um atributo de uma instância dessa classe, o método
obterá o objeto da instância como seu primeiro argumento (que geralmente é chamado de self). Consulte função e escopo aninhado.

ordem de resolução de método Ordem de resolução de método é a ordem na qual as classes base são procuradas por um membro durante a
consulta. Consulte a ordem de resolução do método Python 2.3 para obter detalhes do algoritmo usado pelo interpretador Python desde a
versão 2.3.

módulo Um objeto que serve como uma unidade organizacional do código Python. Os módulos têm um namespace contendo dados arbitrários
Objetos Python. Os módulos são carregados no Python pelo processo de importação.

Veja também pacote.

especificação do módulo Um namespace contendo as informações relacionadas à importação usadas para carregar um módulo. Uma instância
de importlib.machinery.ModuleSpec.

MRO Ver ordem de resolução do método.

mutável Objetos mutáveis podem mudar seu valor, mas manter seu id(). Veja também imutável.

tupla nomeada O termo “tupla nomeada” se aplica a qualquer tipo ou classe herdada de tupla e cujos elementos indexáveis também são
acessíveis usando atributos nomeados. O tipo ou classe também pode ter outros recursos.

Vários tipos integrados são tuplas nomeadas, incluindo os valores retornados por time.localtime() e os. Estado(). Outro exemplo é
sys.float_info:

>>> sys.float_info[1] 1024 # acesso indexado

>>> sys.float_info.max_exp 1024 # acesso ao campo nomeado

>>> isinstance(sys.float_info, tupla) # tipo de tupla


Verdadeiro

Algumas tuplas nomeadas são tipos internos (como os exemplos acima). Alternativamente, uma tupla nomeada pode ser criada a partir de
uma definição de classe regular que herda da tupla e que define campos nomeados. Essa classe pode ser escrita à mão ou pode ser
criada com a função de fábrica collections.namedtuple(). A última técnica também adiciona alguns métodos extras que podem não ser
encontrados em tuplas nomeadas escritas à mão ou incorporadas.

namespace O local onde uma variável é armazenada. Namespaces são implementados como dicionários. Existem os namespaces locais, globais
e integrados, bem como namespaces aninhados em objetos (em métodos). Os namespaces oferecem suporte à modularidade, evitando
conflitos de nomenclatura. Por exemplo, as funções builtins.open e os.open() são diferenciadas por seus namespaces. Os namespaces
também ajudam na legibilidade e na manutenção, deixando claro qual módulo implementa uma função. Por exemplo, escrever
random.seed() ou itertools.islice() deixa claro que essas funções são implementadas pelos módulos random e itertools, respectivamente.

129
Machine Translated by Google

Tutorial do Python, versão 3.11.3

pacote de namespace A PEP 420 pacote que serve apenas como um contêiner para subpacotes. Os pacotes de namespace podem não ter representação
física e, especificamente, não são como um pacote regular porque não têm __init__. arquivo py.

Veja também módulo.

escopo aninhado A capacidade de se referir a uma variável em uma definição envolvente. Por exemplo, uma função definida dentro de outra função pode se
referir a variáveis na função externa. Observe que os escopos aninhados por padrão funcionam apenas para referência e não para atribuição. As
variáveis locais lêem e escrevem no escopo mais interno. Da mesma forma, as variáveis globais leem e gravam no namespace global. O não local
permite a gravação em escopos externos.

classe de novo estilo Nome antigo para o tipo de classe agora usado para todos os objetos de classe. Nas versões anteriores do Python, apenas as classes
de novo estilo podiam usar os recursos mais novos e versáteis do Python, como __slots__, descritores, propriedades, __getattribute__(), métodos de
classe e métodos estáticos.

objeto Qualquer dado com estado (atributos ou valor) e comportamento definido (métodos). Também a classe base final de qualquer
classe de novo estilo.

pacote Um módulo Python que pode conter submódulos ou recursivamente, subpacotes. Tecnicamente, um pacote é um Python
módulo com um atributo __path__.

Consulte também pacote regular e pacote de namespace.

parâmetro Uma entidade nomeada em uma definição de função (ou método) que especifica um argumento (ou, em alguns casos, argumentos)
que a função pode aceitar. Existem cinco tipos de parâmetro:

• positional-or-keyword: especifica um argumento que pode ser passado posicionalmente ou como um argumento de palavra-chave.
Este é o tipo padrão de parâmetro, por exemplo foo e bar no seguinte:

def func(foo, bar=Nenhum): ...

• somente posicional: especifica um argumento que pode ser fornecido apenas por posição. Parâmetros somente posicionais podem ser definidos
incluindo um caractere / na lista de parâmetros da definição de função após eles, por exemplo posonly1 e posonly2 no seguinte:

def func(posonly1, posonly2, /, positional_or_keyword): ...

• somente palavra-chave: especifica um argumento que pode ser fornecido somente por palavra-chave. Parâmetros somente de palavra-chave
podem ser definidos incluindo um único parâmetro var-positional ou * simples na lista de parâmetros da definição de função antes deles, por
exemplo kw_only1 e kw_only2 no seguinte:

def func(arg, *, kw_only1, kw_only2): ...

• var-positional: especifica que uma sequência arbitrária de argumentos posicionais pode ser fornecida (além de quaisquer argumentos posicionais
já aceitos por outros parâmetros). Esse parâmetro pode ser definido acrescentando * ao nome do parâmetro, por exemplo, args no seguinte:

def func(*args, **kwargs): ...

• var-keyword: especifica que muitos argumentos de palavra-chave podem ser fornecidos arbitrariamente (além de qualquer argumento de
palavra-chave já aceito por outros parâmetros). Tal parâmetro pode ser definido prefixando o nome do parâmetro com **, por exemplo kwargs
no exemplo acima.

Os parâmetros podem especificar argumentos opcionais e obrigatórios, bem como valores padrão para alguns argumentos opcionais.

Consulte também a entrada do glossário de argumentos , a pergunta do FAQ sobre a diferença entre argumentos e parâmetros, a classe
inspect.Parameter, a seção de função e PEP 362.

entrada de caminho Um único local no caminho de importação que o localizador baseado em caminho consulta para encontrar módulos para importação.

130 Apêndice A. Glossário


Machine Translated by Google

Tutorial do Python, versão 3.11.3

localizador de entrada de caminho Um localizador retornado por um callable em sys.path_hooks (ou seja, um gancho de entrada de caminho) que sabe como
localizar módulos com uma entrada de caminho.

Consulte importlib.abc.PathEntryFinder para obter os métodos que os localizadores de entrada de caminho implementam.

gancho de entrada de caminho Um callable na lista sys.path_hook que retorna um localizador de entrada de caminho se souber como localizar módulos em uma
entrada de caminho específica.

localizador baseado em caminho Um dos localizadores de meta caminho padrão que pesquisa um caminho de importação para módulos.

objeto semelhante a caminho Um objeto que representa um caminho de sistema de arquivos. Um objeto semelhante a um caminho é um objeto str ou bytes que
representa um caminho ou um objeto que implementa o protocolo os.PathLike. Um objeto que suporta o protocolo os.PathLike pode ser convertido em um
caminho de sistema de arquivos str ou bytes chamando a função os.fspath(); os. fsdecode() e os.fsencode() podem ser usados para garantir um resultado
str ou bytes, respectivamente.
Introduzido por PEP 519.

Proposta de aprimoramento do PEP Python. Um PEP é um documento de design que fornece informações para a comunidade Python ou descreve um novo recurso
para Python ou seus processos ou ambiente. Os PEPs devem fornecer uma especificação técnica concisa e uma justificativa para os recursos propostos.

Os PEPs devem ser os principais mecanismos para propor novos recursos importantes, para coletar informações da comunidade sobre um problema e para
documentar as decisões de design que foram para o Python. O autor do PEP é responsável por construir o consenso dentro da comunidade e documentar
as opiniões divergentes.

Ver PEP 1.

parte Um conjunto de arquivos em um único diretório (possivelmente armazenado em um arquivo zip) que contribui para um pacote de namespace, conforme definido
no PEP 420.

argumento posicional Ver argumento.

API provisória Uma API provisória é aquela que foi deliberadamente excluída das garantias de compatibilidade com versões anteriores da biblioteca padrão. Embora
grandes mudanças em tais interfaces não sejam esperadas, desde que sejam marcadas como provisórias, mudanças incompatíveis com versões anteriores
(até e incluindo a remoção da interface) podem ocorrer se consideradas necessárias pelos desenvolvedores principais. Tais alterações não serão feitas
gratuitamente – elas ocorrerão apenas se forem descobertas falhas fundamentais graves que foram perdidas antes da inclusão da API.

Mesmo para APIs provisórias, as alterações incompatíveis com versões anteriores são vistas como uma “solução de último recurso” - todas as tentativas
ainda serão feitas para encontrar uma solução compatível com versões anteriores para quaisquer problemas identificados.

Esse processo permite que a biblioteca padrão continue a evoluir ao longo do tempo, sem travar em erros de projeto problemáticos por longos períodos de
tempo. Consulte PEP 411 para mais detalhes.

pacote provisório Consulte API provisória.

Python 3000 Apelido para a linha de lançamento do Python 3.x (cunhado há muito tempo, quando o lançamento da versão 3 era algo em
o futuro distante.) Isso também é abreviado como "Py3k".

Pythonic Uma ideia ou trecho de código que segue de perto os idiomas mais comuns da linguagem Python, em vez de implementar código usando conceitos
comuns a outras linguagens. Por exemplo, uma expressão comum em Python é repetir todos os elementos de um iterável usando uma instrução for. Muitas
outras linguagens não possuem esse tipo de construção, portanto, pessoas não familiarizadas com Python às vezes usam um contador numérico:

para i no intervalo(len(comida)):
print(comida[i])

Ao contrário do método Pythonic mais limpo:

para peça em comida:


print(piece)

131
Machine Translated by Google

Tutorial do Python, versão 3.11.3

nome qualificado Um nome pontilhado mostrando o “caminho” do escopo global de um módulo para uma classe, função ou método definido
nesse módulo, conforme definido no PEP 3155. Para funções e classes de nível superior, o nome qualificado é igual ao nome do
objeto:

>>> classe C:
... classe D:
... def meth(self):
... passar
...
>>> C.__qualname__
'C'
>>> CD__qualname__
'CD'
>>> CDmeth.__qualname__ 'CDmeth'

Quando usado para se referir a módulos, o nome totalmente qualificado significa todo o caminho pontilhado para o módulo, incluindo
quaisquer pacotes pai, por exemplo, email.mime.text:

>>> importar email.mime.text >>>


email.mime.text.__name__ 'email.mime.text'

contagem de referência O número de referências a um objeto. Quando a contagem de referência de um objeto cai para zero, ele é
desalocado. A contagem de referência geralmente não é visível para o código Python, mas é um elemento-chave da implementação
do CPython . Os programadores podem chamar a função sys.getrefcount() para retornar a contagem de referência para um
determinado objeto.

pacote regular Um pacote tradicional , como um diretório contendo um arquivo __init__.py.

Consulte também pacote de namespace.

__slots__ Uma declaração dentro de uma classe que economiza memória pré-declarando espaço para atributos de instância e eliminando
dicionários de instância. Embora popular, a técnica é um tanto complicada de acertar e é melhor reservada para casos raros em que
há um grande número de instâncias em um aplicativo de memória crítica.

sequence Um iterável que suporta acesso eficiente a elementos usando índices inteiros através do método especial __getitem__() e define
um método __len__() que retorna o tamanho da sequência. Alguns tipos de sequência integrados são lista, str, tupla e bytes. Observe
que dict também oferece suporte a __getitem__() e __len__(), mas é considerado um mapeamento em vez de uma sequência porque
as pesquisas usam chaves imutáveis arbitrárias em vez de números inteiros.

A classe base abstrata collections.abc.Sequence define uma interface muito mais rica que vai além de apenas __getitem__() e
__len__(), adicionando count(), index(), __contains__() e __reversed__(). Os tipos que implementam essa interface expandida podem
ser registrados explicitamente usando register().

compreensão do conjunto Uma forma compacta de processar todos ou parte dos elementos em um iterável e retornar um conjunto com
os resultados. results = {c for c in 'abracadabra' if c not in 'abc'} gera o conjunto de strings {'r', 'd'}. Veja compreensões.

despacho único Uma forma de despacho de função genérica em que a implementação é escolhida com base no tipo de um único
argumento.

fatia Um objeto geralmente contendo uma parte de uma sequência. Uma fatia é criada usando a notação subscrita, [] com dois pontos entre
os números quando vários são fornecidos, como em nome_da_variável[1:3:5]. A notação de colchete (subscrito) usa objetos de fatia
internamente.

método especial Um método chamado implicitamente pelo Python para executar uma determinada operação em um tipo, como adição.
Esses métodos têm nomes começando e terminando com sublinhados duplos. Métodos especiais são documentados em specialnames.

132 Apêndice A. Glossário


Machine Translated by Google

Tutorial do Python, versão 3.11.3

instrução Uma instrução faz parte de um conjunto (um “bloco” de código). Uma declaração é uma expressão ou uma de várias
construções com uma palavra-chave, como if, while ou for.

referência forte Na API C do Python, uma referência forte é uma referência a um objeto que incrementa a referência do objeto
count quando ele é criado e diminui a contagem de referência do objeto quando ele é excluído.

A função Py_NewRef() pode ser usada para criar uma referência forte a um objeto. Normalmente, a função Py_DECREF() deve ser chamada na
referência forte antes de sair do escopo da referência forte, para evitar o vazamento de uma referência.

Veja também referência emprestada.

codificação de texto Uma string em Python é uma sequência de pontos de código Unicode (no intervalo U+0000–U+10FFFF). Para armazenar ou
transferir uma string, ela precisa ser serializada como uma sequência de bytes.

Serializar uma string em uma sequência de bytes é conhecido como “codificação” e recriar a string a partir da sequência de bytes é conhecido como
“decodificação”.

Há uma variedade de codecs de serialização de texto diferentes, que são chamados coletivamente de “codificações de texto”.

arquivo de texto Um objeto de arquivo capaz de ler e gravar objetos str. Freqüentemente, um arquivo de texto realmente acessa um fluxo de dados
orientado a bytes e lida com a codificação de texto automaticamente. Exemplos de arquivos de texto são arquivos abertos no modo de texto ('r' ou
'w'), sys.stdin, sys.stdout e instâncias de io.StringIO.

Consulte também arquivo binário para obter um objeto de arquivo capaz de ler e gravar objetos semelhantes a bytes.

cadeia de caracteres com aspas triplas Uma cadeia de caracteres vinculada por três ocorrências de aspas (”) ou apóstrofe (').
Embora eles não forneçam nenhuma funcionalidade não disponível com strings entre aspas simples, eles são úteis por vários motivos. Eles
permitem que você inclua aspas simples e duplas sem escape em uma string e podem abranger várias linhas sem o uso do caractere de
continuação, tornando-os especialmente úteis ao escrever docstrings.

type O tipo de um objeto Python determina que tipo de objeto ele é; todo objeto tem um tipo. O tipo de um objeto é
acessível como seu atributo __class__ ou pode ser recuperado com type(obj).

alias de tipo Um sinônimo para um tipo, criado pela atribuição do tipo a um identificador.

Aliases de tipo são úteis para simplificar dicas de tipo. Por exemplo:

def remove_gray_shades(
colors: list[tuple[int, int, int]]) -> list[tuple[int, int, int]]:
passar

poderia ser mais legível assim:

cor = tupla[int, int, int]

def remove_gray_shades(colors: list[Color]) -> list[Color]:


passar

Veja digitação e PEP 484, que descrevem esta funcionalidade.

dica de tipo Uma anotação que especifica o tipo esperado para uma variável, um atributo de classe ou um parâmetro ou retorno de função
valor.

As dicas de tipo são opcionais e não são impostas pelo Python, mas são úteis para ferramentas de análise de tipo estático e ajudam IDEs com
conclusão e refatoração de código.

Dicas de tipo de variáveis globais, atributos de classe e funções, mas não variáveis locais, podem ser acessadas usando a digitação.get_type_hints().

Veja digitação e PEP 484, que descrevem esta funcionalidade.

133
Machine Translated by Google

Tutorial do Python, versão 3.11.3

novas linhas universais Uma maneira de interpretar fluxos de texto em que todos os itens a seguir são reconhecidos como terminando uma
linha: a convenção de fim de linha do Unix '\n', a convenção do Windows '\r\n' e a antiga convenção do Macintosh ' \r'. Consulte PEP 278
e PEP 3116, bem como bytes.splitlines() para uso adicional.

anotação de variável Uma anotação de uma variável ou um atributo de classe.

Ao anotar uma variável ou um atributo de classe, a atribuição é opcional:

classe C:
campo: 'anotação'

Anotações de variáveis são geralmente usadas para dicas de tipo: por exemplo, espera-se que esta variável receba valores int:

contagem: int = 0

A sintaxe de anotação de variável é explicada na seção annassign.

Consulte a anotação de função, PEP 484 e PEP 526, que descrevem esta funcionalidade. Consulte também o tutorial de anotações para
obter as melhores práticas para trabalhar com anotações.

ambiente virtual Um ambiente de tempo de execução isolado cooperativamente que permite que usuários e aplicativos Python instalem e
atualizem pacotes de distribuição Python sem interferir no comportamento de outros aplicativos Python em execução no mesmo sistema.

Veja também venv.

máquina virtual Um computador definido inteiramente em software. A máquina virtual do Python executa o bytecode emitido pelo compilador de
bytecode.

Zen of Python Lista de princípios e filosofias de design do Python que são úteis para entender e usar a linguagem. A listagem pode ser encontrada
digitando “importar isto” no prompt interativo.

134 Apêndice A. Glossário


Machine Translated by Google

APÊNDICE

SOBRE ESTES DOCUMENTOS

Esses documentos são gerados a partir de reStructuredText fontes por Sphinx, um processador de documentos escrito especificamente para
a documentação do Python.

O desenvolvimento da documentação e sua cadeia de ferramentas é um esforço totalmente voluntário, assim como o próprio Python. Se você
quiser contribuir, dê uma olhada na página de relatórios de bugs para obter informações sobre como fazê-lo. Novos voluntários são sempre
bem vindos!

Muitos agradecimentos vão para:

• Fred L. Drake, Jr., criador do conjunto de ferramentas de documentação Python original e autor de grande parte do conteúdo;

• os Docutils projeto de criação do reStructuredText e da suíte Docutils;

• Fredrik Lundh por seu projeto Alternative Python Reference, do qual Sphinx obteve muitas boas ideias.

B.1 Contribuidores para a documentação do Python

Muitas pessoas contribuíram para a linguagem Python, a biblioteca padrão do Python e a documentação do Python. Ver Diversos/ACKS na
distribuição de origem do Python para obter uma lista parcial de colaboradores.

É somente com as informações e contribuições da comunidade Python que o Python tem uma documentação tão maravilhosa – Obrigado!

135
Machine Translated by Google

Tutorial do Python, versão 3.11.3

136 Apêndice B. Sobre estes documentos


Machine Translated by Google

APÊNDICE

HISTÓRIA E LICENÇA

C.1 Histórico do software

O Python foi criado no início dos anos 1990 por Guido van Rossum no Stichting Mathematisch Centrum (CWI, consulte https://www.cwi.nl/ ) na Holanda
como sucessora de uma linguagem chamada ABC. Guido continua sendo o principal autor do Python, embora inclua muitas contribuições de outros.

Em 1995, Guido continuou seu trabalho em Python na Corporation for National Research Initiatives (CNRI, consulte https: //www.cnri.reston.va.us/) em
Reston, Virgínia, onde lançou várias versões do software.

Em maio de 2000, Guido e a equipe principal de desenvolvimento do Python mudaram-se para BeOpen.com para formar a equipe BeOpen PythonLabs.
Em outubro do mesmo ano, a equipe do PythonLabs mudou-se para a Digital Creations (agora Zope Corporation; consulte https://www.zope.org/ ). Em
2001, a Python Software Foundation (PSF, consulte https://www.python.org/psf/) foi formada, uma organização sem fins lucrativos criada
especificamente para possuir Propriedade Intelectual relacionada a Python. A Zope Corporation é um membro patrocinador do PSF.

Todas as versões do Python são de código aberto (consulte https://opensource.org/ para a Definição de Código Aberto). Historicamente, a maioria,
mas não todos, os lançamentos do Python também são compatíveis com GPL; a tabela abaixo resume os vários lançamentos.

Liberar Derivado do ano Proprietário Compatível com GPL?


0,9,0 a 1,2 n/a 1,3 a 1,5,2 1991-1995 CIO sim
1,2 1,6 1,5,2 1995-1999 CNRI 2000 Sim
CNRI não

2.0 1,6 2000 BeOpen.com no CNRI


1.6.1 1,6 2001 PSF não

2.1 2,0+1,6,1 2001 não

2.0.1 2.0+1.6.1 2001 PSF sim


2.1.1 2.1+2.0.1 2001 PSF Sim
2.1.2 2.1.1 2002 PSF sim
2.1.3 2.1.2 2.2 e acima 2.1.1 2002 PSF sim
2001-agora PSF Sim

Nota: Compatível com GPL não significa que estamos distribuindo Python sob a GPL. Todas as licenças Python, ao contrário da GPL, permitem que
você distribua uma versão modificada sem fazer alterações em código aberto. As licenças compatíveis com GPL permitem combinar o Python com
outro software lançado sob a GPL; os outros não.

Obrigado aos muitos voluntários externos que trabalharam sob a direção de Guido para tornar essas liberações possíveis.

137
Machine Translated by Google

Tutorial do Python, versão 3.11.3

C.2 Termos e condições para acessar ou usar o Python

O software Python e a documentação são licenciados sob o contrato de licença PSF.

A partir do Python 3.8.6, exemplos, receitas e outros códigos na documentação são licenciados sob o Contrato de licença PSF e a licença Zero-Clause BSD.

Alguns softwares incorporados ao Python estão sob licenças diferentes. As licenças são listadas com o código correspondente a essa
licença. Consulte Licenças e Reconhecimentos para Software Incorporado para obter uma lista incompleta dessas licenças.

C.2.1 CONTRATO DE LICENÇA PSF PARA PYTHON 3.11.3

1. Este CONTRATO DE LICENÇA é celebrado entre a Python Software Foundation ("PSF"),ÿ


ÿe o

Indivíduo ou Organização ("Licenciado") acessando e usandoÿ ÿO software Python 3.11.3 na forma de fonte ou binária e sua documentação
associada.

2. Sujeito aos termos e condições deste Contrato de Licença, PSF por meio deste
concede ao Licenciado uma licença mundial não exclusiva, isenta de royalties para ÿ ÿ reproduzir, analisar, testar, executar e/ou exibir
publicamente,
preparar trabalhos derivados, distribuir e usar o Python 3.11.3 sozinho ou em qualquer versão derivada, desde que , no entanto, o Contrato de
Licença do PSF e o aviso do PSFÿ ÿde

copyright, ou seja, "Copyright © 2001-2023 Python Software Foundation; Allÿ ÿRights Reserved" são retidos apenas no Python 3.11.3 ou em
qualquer
versão derivada preparada pelo Licenciado.

3. Caso o Licenciado prepare um trabalho derivado baseado ou


incorpore o Python 3.11.3 ou qualquer parte dele e deseje disponibilizar o trabalho derivado para outros conforme fornecido neste
documento, então o Licenciadoÿ ÿ concorda em incluir em qualquer trabalho um breve resumo das alterações feitas noÿ ÿPython 3.11.3 .

4. A PSF está disponibilizando o Python 3.11.3 para o Licenciado "COMO ESTÁ".


A PSF NÃO FAZ REPRESENTAÇÕES OU GARANTIAS, EXPRESSAS OU IMPLÍCITAS. A TIPO DE EXEMPLO, MAS NÃO LIMITAÇÃO, PSF NÃO FAZ E
SE ISENTA DE QUALQUER REPRESENTAÇÃOÿ ÿOU

GARANTIA DE COMERCIABILIDADE OU ADEQUAÇÃO PARA QUALQUER FINALIDADE ESPECÍFICA OU QUEÿ

ÿO
O USO DO PYTHON 3.11.3 NÃO INFRINGIRÁ NENHUM DIREITO DE TERCEIROS.

5. A PSF NÃO SERÁ RESPONSÁVEL PERANTE O LICENCIADO OU QUAISQUER OUTROS USUÁRIOS DE PYTHON 3.11.3

POR QUAISQUER DANOS INCIDENTAIS, ESPECIAIS OU CONSEQUENTES OU PERDA COMO RESULTADOÿ


ÿOF

MODIFICAR, DISTRIBUIR OU DE OUTRA FORMA USAR PYTHON 3.11.3, OU QUALQUERÿ


ÿDERIVATIVO

DISSO, MESMO SE AVISADO DE SUA POSSIBILIDADE.

138 Apêndice C. História e Licença


Machine Translated by Google

Tutorial do Python, versão 3.11.3

6. Este Contrato de Licença será rescindido automaticamente em caso de violação materialÿ


ÿdos
seus termos e condições.

7. Nada neste Contrato de Licença será considerado como criando qualquerÿ ÿrelação

de agência, parceria ou joint venture entre a PSF e o Licenciado. Estaÿ ÿLicença

O acordo não concede permissão para usar marcas registradas ou nomes comerciais da PSF emÿ
ÿa

sentido de marca registrada para endossar ou promover produtos ou serviços do Licenciado, ouÿ

ÿqualquer terceiro.

8. Ao copiar, instalar ou usar o Python 3.11.3, o Licenciado concorda em cumprir os termos e condições deste Contrato de Licença.

C.2.2 CONTRATO DE LICENÇA BEOPEN.COM PARA PYTHON 2.0

CONTRATO DE LICENÇA DE CÓDIGO ABERTO BEOPEN PYTHON VERSÃO 1

1. Este CONTRATO DE LICENÇA é celebrado entre BeOpen.com ("BeOpen"), com escritório em


160 Saratoga Avenue, Santa Clara, CA 95051, e o Indivíduo ou Organização ("Licenciado") acessando e de outra forma usando este software na forma de fonte ou
binária e sua documentação associada ("o Software").

2. Sujeito aos termos e condições deste Contrato de licença BeOpen Python,


A BeOpen concede ao Licenciado uma licença mundial não exclusiva, isenta de royalties para reproduzir, analisar, testar, executar e/ou exibir publicamente, preparar
trabalhos derivados, distribuir e, de outra forma, usar o Software sozinho ou em qualquer versão derivada, desde que , no entanto, que a Licença BeOpen Python é retida
no Software, isoladamente ou em qualquer versão derivada preparada pelo Licenciado.

3. A BeOpen está disponibilizando o Software para o Licenciado "COMO ESTÁ".


A BEOPEN NÃO FAZ REPRESENTAÇÕES OU GARANTIAS, EXPRESSAS OU IMPLÍCITAS. A título de exemplo, mas não de limitação, a BEOPEN NÃO FAZ E
SE ISENTA DE QUALQUER REPRESENTAÇÃO OU GARANTIA DE COMERCIABILIDADE OU ADEQUAÇÃO PARA QUALQUER FINALIDADE ESPECÍFICA OU QUE
O
O USO DO SOFTWARE NÃO INFRINGIRÁ NENHUM DIREITO DE TERCEIROS.

4. A BEOPEN NÃO SERÁ RESPONSÁVEL PERANTE O LICENCIADO OU QUAISQUER OUTROS USUÁRIOS DO SOFTWARE POR

QUAISQUER DANOS OU PERDAS INCIDENTAIS, ESPECIAIS OU CONSEQUENTES COMO RESULTADO DO USO,


MODIFICAR OU DISTRIBUIR O SOFTWARE, OU QUALQUER DERIVADO DELE, MESMO SE
AVISADO DA POSSIBILIDADE DE MESMO.

5. Este Contrato de Licença será rescindido automaticamente em caso de violação material de


seus termos e condições.

6. Este Contrato de Licença será regido e interpretado em todos os aspectos pela lei do Estado da Califórnia, excluindo conflitos de provisões legais.

Nada neste Contrato de Licença deve ser considerado para criar qualquer relação de agência, parceria ou joint venture entre a BeOpen e o Licenciado. Este Contrato
de Licença não concede permissão para usar marcas registradas ou nomes comerciais da BeOpen no sentido de marca registrada para endossar ou promover produtos
ou serviços do Licenciado ou de terceiros. Como exceção, os logotipos "BeOpen Python" disponíveis em http://www.pythonlabs.com/logos.html podem ser usados de
acordo com as permissões (continua na próxima página)

C.2. Termos e condições para acessar ou usar o Python 139


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

concedido nessa página da web.

7. Ao copiar, instalar ou usar o software, o Licenciado concorda em ser


regido pelos termos e condições deste Contrato de Licença.

C.2.3 CONTRATO DE LICENÇA CNRI PARA PYTHON 1.6.1

1. Este CONTRATO DE LICENÇA é celebrado entre a Corporação para Pesquisa Nacional


Iniciativas, com escritório em 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), e o Indivíduo ou Organização ("Licenciado") acessando e
usando o software Python 1.6.1 na forma de código-fonte ou binário e sua documentação associada.

2. Sujeito aos termos e condições deste Contrato de Licença, a CNRI por meio deste
concede ao Licenciado uma licença mundial não exclusiva e isenta de royalties para reproduzir, analisar, testar, executar e/ou exibir publicamente,
preparar trabalhos derivados, distribuir e usar o Python 1.6.1 sozinho ou em qualquer versão derivada, desde que, no entanto , que o Contrato
de licença da CNRI e o aviso de direitos autorais da CNRI, ou seja, "Copyright © 1995-2001 Corporation for National Research Initiatives; Todos os direitos
reservados" são retidos apenas no Python 1.6.1 ou em qualquer versão derivada preparada pelo Licenciado. Como alternativa, no lugar do Contrato de Licença
da CNRI, o Licenciado pode substituir o seguinte texto (omitindo as aspas): "Python 1.6.1 é disponibilizado sujeito aos termos e condições do Contrato de
Licença da CNRI. Este Contrato, juntamente com o Python 1.6.1, pode ser localizado na Internet usando o seguinte identificador exclusivo e persistente
(conhecido como identificador): 1895.22/1013. Este Contrato também pode ser obtido de um servidor proxy na Internet usando o seguinte
URL: http://hdl.handle.net/ 1895.22/1013."

3. Caso o Licenciado prepare um trabalho derivado baseado ou


incorpore o Python 1.6.1 ou qualquer parte dele e deseje disponibilizar o trabalho derivado para outros conforme fornecido neste documento, o Licenciado
concorda em incluir em qualquer trabalho um breve resumo das alterações feitas no Python 1.6.1.

4. A CNRI está disponibilizando o Python 1.6.1 para o Licenciado "COMO ESTÁ". CNRI
NÃO FAZ REPRESENTAÇÕES OU GARANTIAS, EXPRESSAS OU IMPLÍCITAS. A TIPO DE EXEMPLO, MAS NÃO LIMITAÇÃO, CNRI NÃO FAZ E SE ISENTA DE
QUALQUER REPRESENTAÇÃO OU GARANTIA DE COMERCIABILIDADE OU ADEQUAÇÃO PARA QUALQUER FINALIDADE ESPECÍFICA OU QUE O USO DE

PYTHON 1.6.1 NÃO INFRINGIRÁ NENHUM DIREITO DE TERCEIROS.

5. A CNRI NÃO SERÁ RESPONSÁVEL PERANTE O LICENCIADO OU QUAISQUER OUTROS USUÁRIOS DE PYTHON 1.6.1 POR

QUAISQUER DANOS OU PERDAS INCIDENTAIS, ESPECIAIS OU CONSEQUENTES COMO RESULTADO DE MODIFICAÇÃO,


DISTRIBUIÇÃO OU DE OUTRA FORMA USANDO PYTHON 1.6.1, OU QUALQUER DERIVADO
DISSO, MESMO SE AVISADO DE SUA POSSIBILIDADE.

6. Este Contrato de Licença será rescindido automaticamente em caso de violação material de


seus termos e condições.

7. Este Contrato de Licença será regido pela lei federal de propriedade intelectual dos Estados Unidos, incluindo, sem limitação, a lei federal de direitos autorais
e, na medida em que tal lei federal dos EUA não se aplique, pela lei da Comunidade da Virgínia, excluindo Disposições de conflito de leis da Virgínia.

Não obstante o acima exposto, com relação a trabalhos derivados baseados em Python 1.6.1 que incorporam material não separável que foi distribuído
anteriormente sob a GNU General Public License (GPL), a lei da Commonwealth of

(continua na próxima página)

140 Apêndice C. História e Licença


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

A Virgínia regerá este Contrato de Licença apenas quanto a questões decorrentes ou relacionadas aos Parágrafos 4, 5 e 7 deste Contrato de Licença. Nada neste
Contrato de Licença será considerado como criando qualquer relação de representação, parceria ou joint venture entre a CNRI e o Licenciado. Este Contrato de
Licença não concede permissão para usar marcas registradas ou nomes comerciais da CNRI no sentido de marca registrada para endossar ou promover
produtos ou serviços do Licenciado ou de terceiros.

8. Ao clicar no botão "ACEITAR" onde indicado, ou ao copiar, instalar ou usar o Python 1.6.1, o Licenciado concorda em cumprir os termos e condições deste Contrato de
Licença.

C.2.4 CONTRATO DE LICENÇA CWI PARA PYTHON 0.9.0 ATÉ 1.2

Copyright © 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, Holanda. Todos os direitos reservados.

É concedida permissão para usar, copiar, modificar e distribuir este software e sua documentação para qualquer finalidade e sem taxa, desde que
o aviso de direitos autorais acima apareça em todas as cópias e que tanto o aviso de direitos autorais quanto o aviso de permissão apareçam na documentação de
suporte, e que o nome Stichting Mathematisch Centrum ou CWI não seja usado em propaganda ou publicidade relacionada à distribuição do software sem
permissão prévia específica por escrito.

STICHTING MATHEMATISCH CENTRUM RENUNCIA A TODAS AS GARANTIAS COM RELAÇÃO A ESTE

SOFTWARE, INCLUINDO TODAS AS GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO, EM NENHUM CASO A STICHTING MATHEMATISCH
CENTRUM SERÁ RESPONSÁVEL POR QUAISQUER DANOS ESPECIAIS, INDIRETOS OU CONSEQUENTES OU QUAISQUER DANOS RESULTANTES DE
PERDA DE USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU OUTRA AÇÃO ILÍCITA, RESULTANTE OU RELACIONADA
AO USO OU DESEMPENHO DESTE SOFTWARE.

C.2.5 LICENÇA BSD DE CLÁUSULA ZERO PARA CÓDIGO NO DOCUMENTO PYTHON 3.11.3
TAÇÃO

É concedida permissão para usar, copiar, modificar e/ou distribuir este software para qualquer finalidade, com ou sem taxa.

O SOFTWARE É FORNECIDO "COMO ESTÁ" E O AUTOR RENUNCIA A TODAS AS GARANTIAS COM


EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO TODAS AS GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE

E ADEQUAÇÃO. EM NENHUM CASO O AUTOR SERÁ RESPONSÁVEL POR QUALQUER COISA ESPECIAL, DIRETA,
DANOS INDIRETOS OU CONSEQUENCIAIS OU QUAISQUER DANOS RESULTANTES DE
PERDA DE USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
OUTRAS AÇÕES DELICIOSAS, DECORRENTES DE OU EM CONEXÃO COM O USO OU
DESEMPENHO DESTE SOFTWARE.

C.2. Termos e condições para acessar ou usar o Python 141


Machine Translated by Google

Tutorial do Python, versão 3.11.3

C.3 Licenças e Reconhecimentos para Software Incorporado

Esta seção é uma lista incompleta, mas crescente, de licenças e reconhecimentos para software de terceiros incorporados
na distribuição do Python.

C.3.1 Mersenne Twister


O módulo _random inclui código baseado em um download de http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/
emt19937ar.html . A seguir estão os comentários literais do código original:

Um programa C para MT19937, com inicialização aprimorada 26/01/2002.


Codificado por Takuji Nishimura e Makoto Matsumoto.

Antes de usar, inicialize o estado usando init_genrand(seed) ou init_by_array(init_key, key_length).

Copyright (C) 1997 - 2002, Makoto Matsumoto e Takuji Nishimura, Todos os direitos reservados.

A redistribuição e o uso em formato fonte e binário, com ou sem modificação, são permitidos desde que sejam atendidas as seguintes
condições:

1. As redistribuições do código-fonte devem manter o aviso de direitos autorais acima, esta lista de condições e o aviso de isenção de
responsabilidade a seguir.

2. As redistribuições em formato binário devem reproduzir os direitos autorais acima


aviso, esta lista de condições e a seguinte isenção de responsabilidade na documentação e/ou outros materiais fornecidos com a distribuição.

3. Os nomes de seus colaboradores não podem ser usados para endossar ou promover produtos derivados deste software sem permissão prévia
específica por escrito.

ESTE SOFTWARE É FORNECIDO PELOS DETENTORES DOS DIREITOS AUTORAIS E COLABORADORES

"COMO ESTÁ" E QUAISQUER GARANTIAS EXPRESSAS OU IMPLÍCITAS, INCLUINDO, SEM LIMITAÇÃO, AS GARANTIAS
IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO PARA UM FIM ESPECÍFICO SÃO REJEITADAS. EM NENHUM CASO O PROPRIETÁRIO
DOS DIREITOS AUTORAIS OU

OS COLABORADORES SERÃO RESPONSÁVEIS POR QUAISQUER DIRETOS, INDIRETOS, INCIDENTAIS, ESPECIAIS,


DANOS EXEMPLARES OU CONSEQUENCIAIS (INCLUINDO, MAS NÃO SE LIMITANDO A,
AQUISIÇÃO DE BENS OU SERVIÇOS SUBSTITUTOS; PERDA DE USO, DADOS OU
LUCROS; OU INTERRUPÇÃO DE NEGÓCIOS) DE QUALQUER CAUSA E EM QUALQUER TEORIA DE
RESPONSABILIDADE, SEJA EM CONTRATO, RESPONSABILIDADE ESTRITA OU ILÍCITO (INCLUINDO
NEGLIGÊNCIA OU DE OUTRA FORMA) DECORRENTES DE QUALQUER FORMA DO USO DESTE
SOFTWARE, MESMO SE AVISADO DA POSSIBILIDADE DE TAIS DANOS.

Qualquer feedback é muito bem-vindo. http://


www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html e-mail: m-mat @ math.sci.hiroshima-u.ac.jp (remova o espaço)

142 Apêndice C. História e Licença


Machine Translated by Google

Tutorial do Python, versão 3.11.3

C.3.2 Soquetes

O módulo de soquete usa as funções getaddrinfo() e getnameinfo(), que são codificadas em arquivos de origem
separados do WIDE Project, https://www.wide.ad.jp/.

Copyright (C) 1995, 1996, 1997 e 1998 WIDE Project.


Todos os direitos reservados.

A redistribuição e o uso nas formas fonte e binária, com ou sem modificação, são permitidos desde que as seguintes condições

são atendidas:
1. As redistribuições do código-fonte devem manter o aviso de direitos autorais acima, esta lista de condições e o aviso de isenção de
responsabilidade a seguir.
2. As redistribuições em formato binário devem reproduzir os direitos autorais acima
aviso, esta lista de condições e a seguinte isenção de responsabilidade na documentação e/ou outros materiais fornecidos com a distribuição.

3. Nem o nome do projeto nem os nomes de seus colaboradores


pode ser usado para endossar ou promover produtos derivados deste software sem permissão prévia específica por escrito.

ESTE SOFTWARE É FORNECIDO PELO PROJETO E COLABORADORES ``COMO ESTÁ'' E

QUAISQUER GARANTIAS EXPRESSAS OU IMPLÍCITAS, INCLUINDO, SEM LIMITAÇÃO, A


GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO PARA UM FIM ESPECÍFICO

SÃO REJEITADAS. EM NENHUM CASO O PROJETO OU OS COLABORADORES SERÃO RESPONSÁVEIS

POR QUALQUER AÇÃO DIRETA, INDIRETA, INCIDENTAL, ESPECIAL, EXEMPLAR OU CONSEQUENCIAL


DANOS (INCLUINDO, MAS NÃO SE LIMITANDO A, AQUISIÇÃO DE BENS SUBSTITUTOS
OU SERVIÇOS; PERDA DE USO, DADOS OU LUCROS; OU INTERRUPÇÃO DE NEGÓCIOS)
QUALQUER CAUSA E EM QUALQUER TEORIA DE RESPONSABILIDADE, SEJA EM CONTRATO, ESTRITA
RESPONSABILIDADE OU ILÍCITO (INCLUINDO NEGLIGÊNCIA OU DE OUTRA FORMA) DECORRENTE DE QUALQUER FORMA
FORA DO USO DESTE SOFTWARE, MESMO SE AVISADO DA POSSIBILIDADE DE
TAIS DANOS.

C.3.3 Serviços de soquete assíncronos

Os módulos asynchat e asyncore contêm o seguinte aviso:

Copyright 1996 por Sam Rushing

Todos os direitos reservados

É concedida permissão para usar, copiar, modificar e distribuir este software e sua documentação para qualquer finalidade e sem taxa,
desde que o aviso de direitos autorais acima apareça em todas as cópias e que tanto o aviso de direitos autorais quanto o
aviso de permissão apareçam na documentação de suporte, e que o nome de Sam Rushing não seja usado em propaganda ou
publicidade referente à distribuição do software sem permissão prévia específica por escrito.

SAM RUSHING ISENTA-SE DE TODAS AS GARANTIAS COM RELAÇÃO A ESTE SOFTWARE,


INCLUINDO TODAS AS GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO, EM
NENHUM EVENTO A SAM RUSHING SERÁ RESPONSÁVEL POR QUALQUER EVENTO ESPECIAL, INDIRETO OU
DANOS CONSEQUENTES OU QUAISQUER DANOS RESULTANTES DA PERDA
DE USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO,
NEGLIGÊNCIA OU OUTRA AÇÃO ILÍCITA, DECORRENTE DE OU EM
CONEXÃO COM O USO OU DESEMPENHO DESTE SOFTWARE.

C.3. Licenças e Reconhecimentos para Software Incorporado 143


Machine Translated by Google

Tutorial do Python, versão 3.11.3

C.3.4 Gerenciamento de cookies

O módulo http.cookies contém o seguinte aviso:

Copyright 2000 por Timothy O'Malley <timo@alum.mit.edu>

Todos os direitos reservados

É concedida permissão para usar, copiar, modificar e distribuir este software e sua documentação para qualquer
finalidade e sem taxa, desde que o aviso de direitos autorais acima apareça em todas as cópias e que tanto o aviso de
direitos autorais quanto o aviso de permissão apareçam na documentação de suporte, e que o nome de Timothy
O'Malley não seja usado em propaganda ou publicidade referente à distribuição do software sem permissão prévia
específica por escrito.

Timothy O'Malley RENUNCIA A TODAS AS GARANTIAS COM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
TODAS AS GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO, EM NENHUM CASO Timothy
O'Malley SERÁ RESPONSÁVEL POR QUAISQUER DANOS ESPECIAIS, INDIRETOS OU CONSEQUENTES OU
QUAISQUER DANOS RESULTANTES DA PERDA DE USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE
CONTRATO, NEGLIGÊNCIA OU OUTRA AÇÃO DELICITA, DECORRENTE OU RELACIONADA AO
USO OU DESEMPENHO DESTE SOFTWARE.

C.3.5 Rastreamento de execução

O módulo trace contém o seguinte aviso:

copyright de partes 2001, Autonomous Zones Industries, Inc., todos os direitos... err... reservados e oferecidos ao público sob os termos
da licença Python 2.2.

Autor: Zooko O'Whielacronx


http://zooko.com/
mailto:zooko@zooko.com

Copyright 2000, Mojam Media, Inc., todos os direitos reservados.


Autor: Skip Montanaro

Copyright 1999, Bioreason, Inc., todos os direitos reservados.


Autor: Andrew Dalke

Copyright 1995-1997, Automatrix, Inc., todos os direitos reservados.


Autor: Skip Montanaro

Copyright 1991-1995, Stichting Mathematisch Centrum, todos os direitos reservados.

É concedida permissão para usar, copiar, modificar e distribuir este software Python e sua documentação associada para qualquer
finalidade sem taxa, desde que o aviso de direitos autorais acima apareça em todas as cópias e que tanto o aviso de direitos
autorais quanto este aviso de permissão apareçam em suporte documentação, e que o nome de Automatrix, Bioreason ou Mojam Media
não seja usado em propaganda ou publicidade pertencente à distribuição do software sem permissão prévia específica por escrito.

144 Apêndice C. História e Licença


Machine Translated by Google

Tutorial do Python, versão 3.11.3

C.3.6 Funções UUencode e UUdecode

O módulo uu contém o seguinte aviso:

Copyright 1994 por Lance Ellinghouse Cathedral City, California Republic,


Estados Unidos da América.
Todos os direitos reservados
É concedida permissão para usar, copiar, modificar e distribuir este software e sua documentação para qualquer finalidade e sem taxa, desde que
o aviso de direitos autorais acima apareça em todas as cópias e que tanto o aviso de direitos autorais quanto o aviso de permissão
apareçam na documentação de suporte, e que o nome de Lance Ellinghouse não seja usado em propaganda ou publicidade pertencente à distribuição
do software sem permissão prévia específica por escrito.

LANCE ELLINGHOUSE RENUNCIA A TODAS AS GARANTIAS COM RELAÇÃO A

ESTE SOFTWARE, INCLUINDO TODAS AS GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO, EM NENHUM CASO O LANCE
ELLINGHOUSE CENTRUM SERÁ RESPONSÁVEL POR QUAISQUER DANOS ESPECIAIS, INDIRETOS OU CONSEQUENTES
OU QUAISQUER DANOS RESULTANTES DE PERDA DE USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO,
NEGLIGÊNCIA OU OUTRA AÇÃO ILÍCITA, RESULTANTE OU RELACIONADA AO USO OU DESEMPENHO DESTE SOFTWARE.

Modificado por Jack Jansen, CWI, julho de 1995:


- Use o módulo binascii para fazer a conversão real linha por linha
entre ascii e binário. Isso resulta em uma aceleração de 1000 vezes. A versão C ainda é 5 vezes mais rápida, no entanto.

- Argumentos mais compatíveis com o padrão Python

C.3.7 Chamadas de procedimento remoto XML

O módulo xmlrpc.client contém o seguinte aviso:


A interface do cliente XML-RPC é

Copyright (c) 1999-2002 por Secret Labs AB


Copyright (c) 1999-2002 por Fredrik Lundh

Ao obter, usar e/ou copiar este software e/ou sua documentação associada, você concorda que leu, entendeu e cumprirá os
seguintes termos e condições:

É concedida permissão para usar, copiar, modificar e distribuir este software e sua documentação associada para qualquer finalidade e
sem taxa, desde que o aviso de direitos autorais acima apareça em todas as cópias e que tanto o aviso de direitos autorais quanto
este aviso de permissão apareçam em suporte documentação e que o nome da Secret Labs AB ou do autor não seja usado em propaganda
ou publicidade relacionada à distribuição do software sem permissão prévia específica por escrito.

SECRET LABS AB E O AUTOR RENUNCIAM A TODAS AS GARANTIAS COM RELAÇÃO

A ESTE SOFTWARE, INCLUINDO TODAS AS GARANTIAS IMPLÍCITAS DE COMERCIALIZAÇÃO E ADEQUAÇÃO. EM NENHUM


CASO O SECRET LABS AB OU O AUTOR

SER RESPONSÁVEL POR QUAISQUER DANOS ESPECIAIS, INDIRETOS OU CONSEQUENTES OU QUALQUER


DANOS DE QUALQUER TIPO RESULTANTES DA PERDA DE USO, DADOS OU LUCROS,
SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU OUTRO DOLO

(continua na próxima página)

C.3. Licenças e Reconhecimentos para Software Incorporado 145


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

AÇÃO DECORRENTE OU RELACIONADA AO USO OU DESEMPENHO DESTE SOFTWARE.

C.3.8 test_epoll

O módulo test_epoll contém o seguinte aviso:

Copyright (c) 2001-2006 Twisted Matrix Laboratories.

A permissão é concedida gratuitamente a qualquer pessoa que obtenha uma cópia deste software e arquivos de documentação associados (o

"Software"), para lidar com o Software sem restrições, incluindo, sem limitação, os direitos de usar, copiar, modificar, fundir, publicar, distribuir,
sublicenciar e/ou vender cópias do Software, e permitir que as pessoas a quem o Software é fornecido para fazê-lo, sujeito às seguintes
condições:

O aviso de direitos autorais acima e este aviso de permissão devem ser incluídos em todas as cópias ou partes substanciais do
Software.

O SOFTWARE É FORNECIDO "COMO ESTÁ", SEM GARANTIA DE QUALQUER TIPO,


EXPRESSA OU IMPLÍCITA, INCLUINDO MAS NÃO SE LIMITANDO ÀS GARANTIAS DE
COMERCIABILIDADE, ADEQUAÇÃO PARA UM FIM ESPECÍFICO E
NÃO INFRAÇÃO. EM NENHUM CASO OS AUTORES OU DETENTORES DOS DIREITOS AUTORAIS SERÃO

RESPONSÁVEL POR QUALQUER RECLAMAÇÃO, DANOS OU OUTRA RESPONSABILIDADE, SEJA EM UMA AÇÃO
DE CONTRATO, ILÍCITO OU DE OUTRA FORMA, DECORRENTE DE, DE OU EM CONEXÃO
COM O SOFTWARE OU O USO OU OUTROS NEGÓCIOS NO SOFTWARE.

C.3.9 Selecionar kqueue

O módulo select contém o seguinte aviso para a interface kqueue:

Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes Todos os direitos reservados.

A redistribuição e o uso em formato fonte e binário, com ou sem modificação, são permitidos desde que sejam atendidas as seguintes
condições:

1. As redistribuições do código-fonte devem manter o aviso de direitos autorais acima, esta lista de condições e o aviso de isenção de
responsabilidade a seguir.
2. As redistribuições em formato binário devem reproduzir os direitos autorais acima
aviso, esta lista de condições e a seguinte isenção de responsabilidade na documentação e/ou outros materiais fornecidos com a distribuição.

ESTE SOFTWARE É FORNECIDO PELO AUTOR E COLABORADORES ``COMO ESTÁ'' E

QUAISQUER GARANTIAS EXPRESSAS OU IMPLÍCITAS, INCLUINDO, SEM LIMITAÇÃO, A


GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO PARA UM FIM ESPECÍFICO

SÃO REJEITADAS. EM NENHUM CASO O AUTOR OU COLABORADORES SERÃO RESPONSÁVEIS

POR QUALQUER AÇÃO DIRETA, INDIRETA, INCIDENTAL, ESPECIAL, EXEMPLAR OU CONSEQUENCIAL


DANOS (INCLUINDO, MAS NÃO SE LIMITANDO A, AQUISIÇÃO DE BENS SUBSTITUTOS
OU SERVIÇOS; PERDA DE USO, DADOS OU LUCROS; OU INTERRUPÇÃO DE NEGÓCIOS)
QUALQUER CAUSA E EM QUALQUER TEORIA DE RESPONSABILIDADE, SEJA EM CONTRATO, ESTRITA
RESPONSABILIDADE OU ILÍCITO (INCLUINDO NEGLIGÊNCIA OU DE OUTRA FORMA) DECORRENTE DE QUALQUER FORMA
(continua na próxima página)

146 Apêndice C. História e Licença


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

FORA DO USO DESTE SOFTWARE, MESMO SE AVISADO DA POSSIBILIDADE DE TAIS DANOS.

C.3.10 SipHash24
O arquivo Python/pyhash.c contém a implementação de Marek Majkowski do algoritmo SipHash24 de Dan Bernstein.
Contém a seguinte nota:

<Licença MIT>

Copyright (c) 2013 Marek Majkowski <marek@popcount.org>

A permissão é concedida, gratuitamente, a qualquer pessoa que obtenha uma cópia deste software e arquivos de
documentação associados (o "Software"), para lidar com o Software sem restrições, incluindo, sem limitação, os direitos de
usar, copiar, modificar, mesclar , publicar, distribuir, sublicenciar e/ou vender cópias do Software e permitir que as pessoas
a quem o Software é fornecido o façam, sujeito às seguintes condições:

O aviso de direitos autorais acima e este aviso de permissão devem ser incluídos em todas as cópias ou partes
substanciais do Software.
</MIT License>

Localização original:
https://github.com/majek/csiphash/

Solução inspirada no código de: Samuel Neves


(supercop/crypto_auth/siphash24/little) djb (supercop/crypto_auth/siphash24/little2)

Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c)

C.3.11 strtod e dtoa


O arquivo Python/dtoa.c, que fornece funções C dtoa e strtod para conversão de duplicatas C de e para strings, é derivado
do arquivo de mesmo nome de David M. Gay, atualmente disponível em https: //web.archive .org/web/ 20220517033456/
http://www.netlib.org/fp/dtoa.c. O arquivo original, conforme recuperado em 16 de março de 2009, contém o seguinte
aviso de direitos autorais e licenciamento:

/************************************************* ***************
*

* O autor deste software é David M. Gay.


*

* Copyright (c) 1991, 2000, 2001 da Lucent Technologies.


*

* Permissão para usar, copiar, modificar e distribuir este software para qualquer
*
propósito sem taxa é concedido, desde que todo este aviso
* está incluído em todas as cópias de qualquer software que seja ou inclua uma cópia ou modificação deste software
*
e em todas as cópias do suporte
* documentação para tal software.
*
* ESTE SOFTWARE ESTÁ SENDO FORNECIDO "COMO ESTÁ", SEM QUALQUER GARANTIA EXPRESSA OU IMPLÍCITA. EM PARTICULAR,
NEM O AUTOR NEM A LUCENT FAZEM QUALQUER * REPRESENTAÇÃO OU GARANTIA DE QUALQUER TIPO RELATIVA À
COMERCIALIZAÇÃO
* DESTE SOFTWARE OU SUA ADEQUAÇÃO PARA QUALQUER FINALIDADE ESPECÍFICA.

(continua na próxima página)

C.3. Licenças e Reconhecimentos para Software Incorporado 147


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


*
************************************************** *************/

C.3.12 OpenSSL
Os módulos hashlib, posix, ssl, crypt usam a biblioteca OpenSSL para desempenho adicional, se disponibilizados pelo
sistema operacional. Além disso, os instaladores do Windows e macOS para Python podem incluir uma cópia das bibliotecas
OpenSSL, por isso incluímos uma cópia da licença OpenSSL aqui:

PROBLEMAS DE LICENÇA
================

O kit de ferramentas OpenSSL permanece sob uma licença dupla, ou seja, as condições da licença OpenSSL e da
licença SSLeay original se aplicam ao kit de ferramentas.
Veja abaixo a atual licença do texto. Na verdade, ambas as licenças são licenças Open Source estilo BSD. Em caso de
problemas de licença relacionados ao OpenSSL, entre em contato com openssl-core@openssl.org.

Licença OpenSSL
---------------

/* =================================================== ==================== * Copyright (c)


1998-2008 O Projeto OpenSSL. Todos os direitos reservados.
*
* A redistribuição e uso em fontes e formas binárias, com ou sem * modificação, são permitidos desde que
as seguintes condições
* são atendidas:
*
* 1. As redistribuições do código-fonte devem manter o aviso de direitos autorais acima, esta lista de
*
condições e o aviso de isenção de responsabilidade a seguir.
*
* 2. As redistribuições em formato binário devem reproduzir o aviso de direitos autorais acima, esta lista de
*
condições e a seguinte isenção de responsabilidade na documentação e/ou outros materiais
*
fornecidos com a distribuição.
*
*
* 3. Todos os materiais publicitários que mencionem recursos ou uso deste
*
o software deve exibir o seguinte reconhecimento: "Este produto inclui software
*
desenvolvido pelo OpenSSL Project para uso no OpenSSL Toolkit. (http://www.openssl.org/)"
*
*
* 4. Os nomes "OpenSSL Toolkit" e "OpenSSL Project" não devem ser usados para
*
endossa ou promove produtos derivados deste software sem permissão prévia por escrito. Para
*
obter permissão por escrito, entre em contato com openssl-core@openssl.org.
*
*
* 5. Os produtos derivados deste software não podem ser chamados de "OpenSSL" nem "OpenSSL"
*
aparecer em seus nomes sem permissão prévia por escrito do Projeto OpenSSL.
*
*
* 6. Redistribuições de qualquer forma devem manter o seguinte
*
reconhecimento: "Este
*
produto inclui software desenvolvido pelo OpenSSL Project para uso no OpenSSL Toolkit (http://
*
www.openssl.org/)"
*
(continua na próxima página)

148 Apêndice C. História e Licença


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)

* ESTE SOFTWARE É FORNECIDO PELO PROJETO OpenSSL ``COMO ESTÁ'' E QUALQUER


* GARANTIAS EXPRESSAS OU IMPLÍCITAS, INCLUINDO, MAS NÃO SE LIMITANDO ÀS
* GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO PARA UM DETERMINADO

* FINALIDADE SÃO REJEITADAS. EM NENHUM CASO O PROJETO OpenSSL OU * SEUS COLABORADORES SERÃO
RESPONSÁVEIS POR QUAISQUER DANOS DIRETOS, INDIRETOS, INCIDENTAIS, ESPECIAIS, EXEMPLARES OU
* CONSEQUENCIAIS (INCLUINDO, MAS * NÃO SE LIMITANDO A, AQUISIÇÃO DE BENS OU SERVIÇOS
SUBSTITUTOS; * PERDA DE USO, DADOS , OU LUCROS; OU INTERRUPÇÃO DE NEGÓCIOS)

* DE QUALQUER CAUSA E EM QUALQUER TEORIA DE RESPONSABILIDADE, SEJA EM CONTRATO, * RESPONSABILIDADE


ESTRITA OU ILÍCITO (INCLUINDO NEGLIGÊNCIA OU DE OUTRA FORMA)
* DECORRENTE DE QUALQUER FORMA DO USO DESTE SOFTWARE, MESMO SE AVISADO * DA
POSSIBILIDADE DE TAIS DANOS.
* ==================================================== ==================
*
* Este produto inclui software criptográfico escrito por Eric Young * (eay@cryptsoft.com). Este produto inclui
software escrito por Tim * Hudson (tjh@cryptsoft.com).

*
*/

Licença SSLeay Original


------------------------

/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)


* Todos os direitos reservados.
*
* Este pacote é uma implementação SSL escrita * por Eric Young
(eay@cryptsoft.com).
* A implementação foi escrita de forma a estar em conformidade com Netscapes SSL.
*
* Esta biblioteca é gratuita para uso comercial e não comercial, desde que * as seguintes condições sejam
atendidas. As seguintes condições * aplicam-se a todos os códigos encontrados nesta distribuição, seja o
código RC4, RSA, * lhash, DES, etc.; não apenas o código SSL. A documentação SSL * incluída nesta
distribuição é coberta pelos mesmos termos de direitos autorais

*
exceto que o titular é Tim Hudson (tjh@cryptsoft.com).
*
* Os direitos autorais permanecem de Eric Young e, como tal, quaisquer avisos de direitos autorais * no código
não devem ser removidos.
* Se este pacote for usado em um produto, Eric Young deve receber a atribuição
*
como autor das partes da biblioteca utilizadas.
* Isso pode ser na forma de uma mensagem de texto na inicialização do programa ou * na documentação
(online ou textual) fornecida com o pacote.
*
* A redistribuição e uso em fontes e formas binárias, com ou sem * modificação, são permitidos desde que as
seguintes condições
* são atendidas:
* 1. As redistribuições do código-fonte devem manter os direitos autorais
*
aviso prévio, esta lista de condições e a seguinte isenção de responsabilidade.
* 2. As redistribuições em formato binário devem reproduzir os direitos autorais acima
*
aviso, esta lista de condições e a seguinte isenção de responsabilidade na documentação e/ou outros
*
materiais fornecidos com a distribuição.
* 3. Todos os materiais publicitários que mencionam recursos ou uso deste software devem exibir o seguinte
*
reconhecimento: "Este produto inclui software criptográfico escrito
*
por
*
Eric Young (eay@cryptsoft.com)"
* A palavra 'criptográfica' pode ser omitida se as rotinas da biblioteca
(continua na próxima página)

C.3. Licenças e Reconhecimentos para Software Incorporado 149


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


*
sendo usados não são criptográficos relacionados :-).
* 4. Se você incluir qualquer código específico do Windows (ou um derivado dele) de
*
o diretório apps (código do aplicativo), você deve incluir um reconhecimento: "Este produto inclui software escrito por Tim Hudson (tjh@cryptsoft.com)"
*
*

* ESTE SOFTWARE É FORNECIDO POR ERIC YOUNG ``COMO ESTÁ'' E


* QUAISQUER GARANTIAS EXPRESSAS OU IMPLÍCITAS, INCLUINDO, SEM LIMITAÇÃO, A
* GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO PARA UM FIM ESPECÍFICO

* SÃO REJEITADOS. EM NENHUM CASO O AUTOR OU COLABORADORES SERÃO RESPONSÁVEIS

* PARA QUALQUER DIRETO, INDIRETO, INCIDENTAL, ESPECIAL, EXEMPLAR OU CONSEQUENCIAL


* DANOS (INCLUINDO, MAS NÃO SE LIMITANDO A, AQUISIÇÃO DE BENS SUBSTITUTOS
* OU SERVIÇOS; PERDA DE USO, DADOS OU LUCROS; OU INTERRUPÇÃO DE NEGÓCIOS)
* DE QUALQUER CAUSA E EM QUALQUER TEORIA DE RESPONSABILIDADE, SEJA EM CONTRATO, ESTRITA
*
RESPONSABILIDADE OU ILÍCITO (INCLUINDO NEGLIGÊNCIA OU DE OUTRA FORMA) DECORRENTE DE QUALQUER FORMA
* FORA DO USO DESTE SOFTWARE, MESMO SE AVISADO DA POSSIBILIDADE DE
* TAIS DANOS.
*

* Os termos de licença e distribuição para qualquer versão publicamente disponível ou * derivados deste código não podem ser alterados. ou seja, este
código não pode simplesmente ser * copiado e colocado sob outra licença de distribuição * [incluindo a GNU Public License.] */

C.3.13 expatriado

A extensão pyexpat é construída usando uma cópia incluída das fontes expat, a menos que a compilação seja
configurada --with-system-expat:

Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
e Clark Cooper

A permissão é concedida gratuitamente a qualquer pessoa que obtenha uma cópia deste software e arquivos de documentação
associados (o
"Software"), para lidar com o Software sem restrições, incluindo, sem limitação, os direitos de usar, copiar, modificar, fundir, publicar,
distribuir, sublicenciar e/ou vender cópias do Software, e permitir que as pessoas a quem o Software é fornecido para fazê-lo, sujeito
às seguintes condições:

O aviso de direitos autorais acima e este aviso de permissão devem ser incluídos em todas as cópias ou partes substanciais do Software.

O SOFTWARE É FORNECIDO "COMO ESTÁ", SEM GARANTIA DE QUALQUER TIPO,


EXPRESSA OU IMPLÍCITA, INCLUINDO MAS NÃO SE LIMITANDO ÀS GARANTIAS DE
COMERCIABILIDADE, ADEQUAÇÃO PARA UM FIM ESPECÍFICO E NÃO VIOLAÇÃO.
EM NENHUM CASO OS AUTORES OU DETENTORES DOS DIREITOS AUTORAIS SERÃO RESPONSÁVEIS POR QUALQUER

RECLAMAÇÃO, DANOS OU OUTRA RESPONSABILIDADE, SEJA EM UMA AÇÃO DE CONTRATO,


ILÍCITO OU DE OUTRA FORMA, DECORRENTE DE, DE OU EM CONEXÃO COM O
SOFTWARE OU O USO OU OUTROS NEGÓCIOS NO SOFTWARE.

150 Apêndice C. História e Licença


Machine Translated by Google

Tutorial do Python, versão 3.11.3

C.3.14 libffi

A extensão _ctypes é construída usando uma cópia incluída das fontes libffi, a menos que a compilação seja
configurada --with-system-libffi:

Copyright (c) 1996-2008 Red Hat, Inc e outros.

A permissão é concedida gratuitamente a qualquer pessoa que obtenha uma cópia deste software e arquivos de documentação associados (o

``Software''), negociar com o Software sem restrições, incluindo, sem limitação, os direitos de usar, copiar, modificar, fundir, publicar, distribuir,
sublicenciar e/ou vender cópias do Software, e permitir que pessoas a quem o Software é fornecido para isso, sujeito às seguintes condições:

O aviso de direitos autorais acima e este aviso de permissão devem ser incluídos em todas as cópias ou partes substanciais do Software.

O SOFTWARE É FORNECIDO ``COMO ESTÁ'', SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO
MAS NÃO SE LIMITANDO ÀS GARANTIAS DE COMERCIALIZAÇÃO, ADEQUAÇÃO A UM DETERMINADO FIM E NÃO VIOLAÇÃO. EM
NENHUM CASO OS AUTORES OU DIREITOS AUTORAIS

OS TITULARES SERÃO RESPONSÁVEIS POR QUALQUER REIVINDICAÇÃO, DANOS OU OUTRA RESPONSABILIDADE,


SEJA EM UMA AÇÃO DE CONTRATO, ILÍCITO OU DE OUTRA FORMA, DECORRENTE DE,
FORA DE OU EM CONEXÃO COM O SOFTWARE OU O USO OU OUTRO
NEGÓCIOS NO SOFTWARE.

C.3.15 zlib

A extensão zlib é construída usando uma cópia incluída das fontes zlib se a versão zlib encontrada no sistema for muito antiga para
ser usada para a compilação:

Copyright (C) 1995-2011 Jean-loup Gailly e Mark Adler

Este software é fornecido 'como está', sem qualquer garantia expressa ou implícita. Em nenhum caso os autores serão responsabilizados
por quaisquer danos decorrentes do uso deste software.

A permissão é concedida a qualquer pessoa para usar este software para qualquer finalidade, incluindo aplicativos comerciais, e para alterá-lo
e redistribuí-lo livremente, sujeito às seguintes restrições:

1. A origem deste software não deve ser deturpada; você não deve alegar que escreveu o software original. Se você usar este software em um
produto, um reconhecimento na documentação do produto seria apreciado, mas não é obrigatório.

2. Versões fonte alteradas devem ser claramente marcadas como tal e não devem ser deturpadas como sendo o software original.

3. Este aviso não pode ser removido ou alterado de qualquer fonte de distribuição.

Jean-loup Gailly jloup@gzip.org Mark Adler


madler@alumni.caltech.edu

C.3. Licenças e Reconhecimentos para Software Incorporado 151


Machine Translated by Google

Tutorial do Python, versão 3.11.3

C.3.16 cfuhash

A implementação da tabela hash usada pelo tracemalloc é baseada no projeto cfuhash:

Copyright (c) 2005 Don Owens Todos os direitos reservados.

Este código é liberado sob a licença BSD:

A redistribuição e o uso nas formas fonte e binária, com ou sem modificação, são permitidos desde que as seguintes condições

são atendidas:

* As redistribuições do código-fonte devem manter o aviso de direitos autorais acima, esta lista de condições e o aviso de isenção de
responsabilidade a seguir.

* As redistribuições em formato binário devem reproduzir o acima


aviso de direitos autorais, esta lista de condições e a seguinte isenção de responsabilidade na documentação e/ou outros
materiais fornecidos
com a distribuição.

* Nem o nome do autor nem os nomes de seus

colaboradores podem ser usados para endossar ou promover produtos derivados deste software sem permissão prévia específica por
escrito.

ESTE SOFTWARE É FORNECIDO PELOS DETENTORES DOS DIREITOS AUTORAIS E COLABORADORES

"COMO ESTÁ" E QUAISQUER GARANTIAS EXPRESSAS OU IMPLÍCITAS, INCLUINDO, MAS NÃO


LIMITADO ÀS GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO
PARA UMA FINALIDADE ESPECÍFICA SÃO REJEITADAS. EM NENHUM CASO O

O PROPRIETÁRIO DOS DIREITOS AUTORAIS OU OS COLABORADORES SERÃO RESPONSÁVEIS POR QUALQUER


DANOS INCIDENTAIS, ESPECIAIS, EXEMPLARES OU CONSEQUENCIAIS
(INCLUINDO, MAS NÃO SE LIMITANDO A, AQUISIÇÃO DE BENS SUBSTITUTOS OU
SERVIÇOS; PERDA DE USO, DADOS OU LUCROS; OU INTERRUPÇÃO DE NEGÓCIOS)
DE QUALQUER CAUSA E EM QUALQUER TEORIA DE RESPONSABILIDADE, SEJA EM CONTRATO, RESPONSABILIDADE
ESTRITA OU ILÍCITO (INCLUINDO NEGLIGÊNCIA OU DE OUTRA FORMA)
DECORRENTE DE QUALQUER FORMA DO USO DESTE SOFTWARE, MESMO SE AVISADO DA POSSIBILIDADE DE TAIS DANOS.

C.3.17 libmpdec
O módulo _decimal é construído usando uma cópia incluída da biblioteca libmpdec, a menos que a compilação seja
configurada --with-system-libmpdec:

Direitos autorais (c) 2008-2020 Stefan Krah. Todos os direitos reservados.

A redistribuição e o uso nas formas fonte e binária, com ou sem modificação, são permitidos desde que as seguintes condições

são atendidas:

1. As redistribuições do código-fonte devem manter o aviso de direitos autorais acima, esta lista de condições e o aviso de isenção de
responsabilidade a seguir.

2. As redistribuições em formato binário devem reproduzir os direitos autorais acima


aviso, esta lista de condições e a seguinte isenção de responsabilidade na documentação e/ou outros materiais fornecidos com a distribuição.

(continua na próxima página)

152 Apêndice C. História e Licença


Machine Translated by Google

Tutorial do Python, versão 3.11.3

(continuação da página anterior)


ESTE SOFTWARE É FORNECIDO PELO AUTOR E COLABORADORES "COMO ESTÁ" E

QUAISQUER GARANTIAS EXPRESSAS OU IMPLÍCITAS, INCLUINDO, SEM LIMITAÇÃO, A


GARANTIAS IMPLÍCITAS DE COMERCIABILIDADE E ADEQUAÇÃO PARA UM FIM ESPECÍFICO

SÃO REJEITADAS. EM NENHUM CASO O AUTOR OU COLABORADORES SERÃO RESPONSÁVEIS

POR QUAISQUER DANOS DIRETOS, INDIRETOS, INCIDENTAIS, ESPECIAIS, EXEMPLARES OU CONSEQUENTES (INCLUINDO, ENTRE OUTROS,
AQUISIÇÃO DE BENS OU SERVIÇOS SUBSTITUTOS; PERDA DE USO, DADOS OU LUCROS; OU INTERRUPÇÃO DE NEGÓCIOS)

QUALQUER CAUSA E EM QUALQUER TEORIA DE RESPONSABILIDADE, SEJA EM CONTRATO, RESPONSABILIDADE ESTRITA OU ILÍCITO
(INCLUINDO NEGLIGÊNCIA OU DE OUTRA FORMA) DECORRENTE DE QUALQUER FORMA DO USO DESTE SOFTWARE, MESMO SE AVISADO
DA POSSIBILIDADE DE TAIS DANOS.

C.3.18 Conjunto de testes W3C C14N

O conjunto de testes C14N 2.0 no pacote de teste (Lib/test/xmltestdata/c14n-20/) foi recuperado do site W3C
em https://www.w3.org/TR/xml-c14n2-testcases/ e é distribuído sob a licença BSD de 3 cláusulas:

Copyright (c) 2013 W3C(R) (MIT, ERCIM, Keio, Beihang), Todos os direitos reservados.

A redistribuição e o uso nas formas fonte e binária, com ou sem modificação, são permitidos desde que as seguintes condições

são atendidas:

* As redistribuições de obras devem manter o aviso de direitos autorais original,


esta lista de condições e a seguinte isenção de responsabilidade.
* As redistribuições em formato binário devem reproduzir o aviso de direitos autorais original, esta lista de condições e a seguinte isenção de
responsabilidade na documentação e/ou outros materiais fornecidos com a distribuição.

* Nem o nome do W3C nem os nomes de seus colaboradores podem ser usados para endossar ou promover produtos derivados deste trabalho sem
permissão prévia específica por escrito.

ESTE SOFTWARE É FORNECIDO PELOS DETENTORES DOS DIREITOS AUTORAIS E COLABORADORES

"COMO ESTÁ" E QUAISQUER GARANTIAS EXPRESSAS OU IMPLÍCITAS, INCLUINDO, SEM LIMITAÇÃO, AS GARANTIAS IMPLÍCITAS
DE COMERCIABILIDADE E ADEQUAÇÃO PARA UM FIM ESPECÍFICO SÃO REJEITADAS. EM NENHUM CASO OS DIREITOS AUTORAIS

O PROPRIETÁRIO OU OS COLABORADORES SERÃO RESPONSÁVEIS POR QUALQUER COISA DIRETA, INDIRETA, INCIDENTAL,
DANOS ESPECIAIS, EXEMPLARES OU CONSEQUENTES (INCLUINDO, MAS NÃO
LIMITADO A, AQUISIÇÃO DE BENS OU SERVIÇOS SUBSTITUTOS; PERDA DE USO,
DADOS OU LUCROS; OU INTERRUPÇÃO DE NEGÓCIOS) DE QUALQUER CAUSA E DE QUALQUER
TEORIA DA RESPONSABILIDADE, SEJA EM CONTRATO, RESPONSABILIDADE ESTRITA OU ILÍCITO
(INCLUINDO NEGLIGÊNCIA OU OUTROS) DECORRENTES DE QUALQUER FORMA DO USO
DESTE SOFTWARE, MESMO SE AVISADO DA POSSIBILIDADE DE TAIS DANOS.

C.3. Licenças e Reconhecimentos para Software Incorporado 153


Machine Translated by Google

Tutorial do Python, versão 3.11.3

C.3.19 Operação de áudio

O módulo audioop usa o código base no arquivo g771.c do projeto SoX:

Programando os chips de música AdLib/Sound Blaster


FM versão 2.0 (24 de
fevereiro de 1992)
Copyright (c) 1991, 1992 por Jeffrey S. Lee jlee@smylex.uucp
Política de garantia e
direitos autorais Este documento é fornecido
"no estado em que se encontra" e seu autor não oferece nenhuma garantia ou representação, expressa ou
implícita, com relação a seu desempenho de qualidade ou adequação a um propósito específico. Em
nenhum caso o autor deste documento será responsável por danos diretos, indiretos, especiais, incidentais
ou consequentes decorrentes do uso ou incapacidade de usar as informações nele contidas. O uso deste
documento é por sua conta e risco.

Este arquivo pode ser usado e copiado livremente desde que os avisos de direitos autorais aplicáveis
sejam mantidos e nenhuma modificação seja feita no texto do documento. Nenhum dinheiro será cobrado por
sua distribuição além dos custos razoáveis de remessa, manuseio e duplicação, nem alterações proprietárias
serão feitas neste documento para que ele não possa ser distribuído livremente. Este documento não pode ser
incluído em materiais publicados ou pacotes comerciais sem o consentimento por escrito de seu autor.

154 Apêndice C. História e Licença


Machine Translated by Google

APÊNDICE

DIREITO AUTORAL

Python e esta documentação é:

Copyright © 2001-2023 Python Software Foundation. Todos os direitos reservados.

Copyright © 2000 BeOpen.com. Todos os direitos reservados.

Copyright © 1995-2000 Corporation for National Research Initiatives. Todos os direitos reservados.

Copyright © 1991-1995 Stichting Mathematisch Centrum. Todos os direitos reservados.

Consulte Histórico e licença para obter informações completas sobre licença e permissões.

155
Machine Translated by Google

Tutorial do Python, versão 3.11.3

156 Apêndice D. Direitos autorais


Machine Translated by Google

ÍNDICE

Não alfabético objeto semelhante a bytes, 123


..., 121
# (hash) C
comentário, chamável, 123
9* retorno de chamada, 123
(asterisco) em chamadas de função, 32 C-contíguo, 123 classe,
** 123 variável
em chamadas de função, 32 de classe, 123 estilo de
2to3, 121 :
(dois codificação, 34
pontos) anotações de função, 34 número complexo, 123
-> gerenciador de contexto,
anotações de função, 34 >>>, 121 123 variável de contexto, 123
__all__, contíguo, 123 co-
56 __future__, rotina, 124 função
126 __slots__, 132 co-rotina, 124
CPython, 124

A D
classe base abstrata, 121 decorador, 124
anotação, 121 descritor, 124
função de dicionário, 124
anotação, 34 compreensão de dicionário, 124
argumento, 121 visualização de dicionário,
gerenciador de contexto assíncrono, 122 124 docstring, 124
gerador assíncrono, 122 iterador docstrings, 25, 33
gerador assíncrono, 122 iterável assíncrono , 122 strings de documentação, 25, 33 duck-
iterador assíncrono, 122 atributo, 122 typing, 124
aguardável, 122
E
EAFP, 124
variáveis de ambiente
B CAMINHO, 51, 119
BDFL, 122 PYTHONPATH, 51, 53
arquivo binário, 122 PYTHONSTARTUP, 120
referência emprestada, 122 expressão, 125
função embutida módulo de extensão, 125
help, 91
open, 63 F
builtins f-string, arquivo
module, 54 125
bytecode, 123 objeto, 63

157
Machine Translated by Google

Tutorial do Python, versão 3.11.3

objeto de arquivo, 125 carregador, 128


objeto semelhante a arquivo, codificação de localidade, 128
125 codificação do sistema de arquivos e manipulador de
M
erros, 125 magic
localizador, 125 divisão de method, 128
piso, 125 para magic method, 128
declaração, 19 mangling
Fortran contíguo, 123 função, 125 name, 86
anotações, 34 mapping, 128
anotação de função, meta path finder, 129 metaclass,
125 129 method, 129
magic, 128
G
object, 81
coleta de lixo, 126 gerador, 126 special, 132
expressão de methodresolution
gerador, 126 iterador de gerador, 126 order, 129 module, 129 builtins, 54 json, 65
função genérica, 126 tipo genérico, search caminho,
126 51 sys, 52

GIL, 126 especificação de


bloqueio de intérprete global, 126 módulo,
129
H MRO, 129
pyc baseado em hash, 126 mutável, 129
hashable, 127
função
N
integrada de ajuda, 91 nome
mangling, 86
EU

tupla nomeada, 129


IDLE, 127 namespace, 129
imutável, 127 pacote de namespace, 130
caminho de importação, escopo aninhado, 130
127 importador, classe de novo estilo, 130
127 importando, 127
interativo, 127 O
interpretado, 127 objeto, 130
desligamento do interpretador, 127 arquivo,
iterável, 127 63 método, 81
iterador, 127 função
interna aberta, 63
J
P
módulo json, 65 pacote, 130
parâmetro, 130
PATH, 51, 119
Função de tecla K , 128 busca
argumento de palavra-chave, 128 de módulo de caminho, 51
localizador baseado em caminho, 131
eu
entrada de caminho, 130
lambda, 128 localizador de entrada de caminho,
LBYL, 128 131 gancho de entrada de
lista, 128 caminho, 131 objeto semelhante a caminho, 131
lista de compreensão, 128 PEP, 131

158 Índice
Machine Translated by Google

Tutorial do Python, versão 3.11.3

porção, 131 para, 19


argumento posicional, 131 API strings, documentação, 25, 33 referência
provisória, 131 pacote forte, 133 codificação de estilo,
provisório, 131 34
Python 3000, 131
Propostas de aprimoramento do Python sistema

PEP 1, 131 módulo, 52


PEP 8, 34
PEP 238, 125 T
PEP 278, 134 codificação de texto, 133
PEP 302, 125, 128 arquivo de texto, 133
PEP 343, 123 string com aspas triplas, 133 tipo, 133
PEP 362, 122, 130 alias de
PEP 411, 131 tipo, 133 dica de tipo,
PEP 420, 125, 130, 131 133
PEP 443, 126
PEP 451, 125 você

PEP 483, 126 novas linhas universais, 134


PEP 484, 34, 121, 125, 126, 133, 134
PEP 492, 122, 124 V
PEP 498, 125 anotação de variável, 134 ambiente
PEP 519, 131 virtual, 134 máquina virtual, 134
PEP 525, 122
PEP 526, 121, 134
PEP 585, 126 Z
PEP 636, 25
Zen de Python, 134
PEP 3107, 34
PEP 3116, 134
PEP 3147, 52
PEP 3155, 132
Pitônico, 131
PYTHONPATH, 51, 53
PYTHONSTARTUP, 120

Q
nome qualificado, 132

R
contagem de referência, 132
pacote regular, 132
RFC
RFC 2822, 96

S
procurar
caminho, módulo, 51
sequência, 132
compreensão de conjunto, 132
despacho único, 132 fatia, 132
método
especial,
132 método
especial, 132 instrução, 133

Índice 159

Você também pode gostar