88
assas 3\WKRQ Trabalho realizado por: Henrique Moura i930483 I SEP Instituto Superior de Engenharia do Porto

WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

  • Upload
    phamthu

  • View
    217

  • Download
    0

Embed Size (px)

Citation preview

Page 1: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

assas

3\WKRQ

Trabalho realizado por: Henrique Moura i930483

ISEP Instituto Superior de Engenharia do Porto

Page 2: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

2

Page 3: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Índice

3

ÍNDICE

Capítulo 1 Introdução 07

Breve introdução histórica 08

Características do Python 08

Librarias do Python 09

Comparação com outras linguagens 10

Java 10

JavaScript 10

Perl 11

Tcl 11

C++ 11

Empresas/Instituições que usam o Python 11

Capítulo 2 O interpretador do Phyton 13

Passar Argumentos 14

Modo Interactivo 15

O Interpretador e o seu Ambiente 15

Tratamento de Erros 15

Scripts executáveis em Python 16

O Arquivo de inicialização para Modo Interactivo 16

Capítulo 3 Uma introdução informal ao Python 17 Utilizando o Python como uma calculadora 18

Números 18

Strings 20

Strings Unicode 24

Listas 26

Primeiros passos em direcção à programação 27

Capítulo 4 Ferramentas de controle de fluxos 31 Construção do if 32

Construção do for 32

Page 4: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

4

A função range() 33

Cláusulas break, continue e else em ciclos 33

Construção pass 34

Funções 34

Parâmetros com valores por defeito 36

Parâmetros na forma Chave-Valor 37

Listas arbitrárias de argumentos 39

Funções Lambda 39

Strings de documentação 40

Capítulo 5 Estruturas de Dados 41 Listas 42

Usando Listas como Pilhas 43

Usando Listas como Filas 43

Ferramentas para programação funcional 44

Abrangência de Listas (List Comprehensions) 45

O comando del 46

Tuplos e Sequências 46

Dicionários 47

Condições 48

Comparando sequências e outros tipos 49

Capítulo 6 Módulos 51

O Caminho de busca dos módulos 53

Arquivos Python “Compilados” 54

Módulos Padrão 55

A Função dir() 55

Pacotes 56

Importando * de um pacote 58

Referências num mesmo pacote 59

Page 5: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Índice

5

Capítulo 7 Entrada e Saída 61 Formatação de Saída 62

Leitura e escrita de arquivos 65

Métodos dos objectos de arquivos 65

O módulo pickle 67

Capítulo 8 Erros e Excepções 69 Erros de sintaxe 70

Excepções 70

Tratamento das Excepções 71

Levantando Excepções 73

Excepções definidas pelo usuário 73

Acções de limpeza 74

Capítulo 9 Classes 75

Uma palavra sobre terminologia 76

Escopos e espaços de nomes no Python 77

Sintaxe da definição de Classes 78

Objectos de Classes 79

Instâncias 80

Métodos dos Objectos 80

Observações aleatórias 81

Herança 83

Herança múltipla 83

Variáveis Privadas 84

Particularidades 85

As Excepções podem ser Classes 85

Capítulo 10 Conclusão 87

JPython (o futuro) 88

Page 6: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

6

Page 7: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Introdução

7

II nntt rr oodduuççããoo

Page 8: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

8

Introdução As linguagens de programação têm sido criadas pelas mais variadas razões. Uma das mais recentes é o Python, uma linguagem que possui características muito semelhantes às das linguagens Perl, Awk entre outras.

A linguagem Python é uma linguagem de alto nível, interpretada, orientada a objecto com uma semântica dinâmica. As suas estruturas de alto nível, combinadas com uma ligação dinâmica tornam-na muito atractiva para desenvolvimento rápido de aplicações, assim como, para uso como linguagem de script ou de ligação entre vários componentes.

A sintaxe simples do Python encoraja a reutilização de código, simplificando a manutenção e a normalização de dados em módulos e pacotes distintos. Esta linguagem, bem como seu código fonte, encontram-se gratuitamente disponível na Internet podendo ser consultado por qualquer interessado sem qualquer encargo. Apesar disso, a linguagem Python é marca registrada do Stichting Mathematisch Centrum de Amsterdam, com todos os direitos reservados.

Breve introdução histórica A linguagem Python foi desenvolvida pelo holandês Guido Van Rossun, no final de 1990. Segundo Van Rossum, a linguagem surgiu enquanto este passava o tempo entre o Natal de 1990 e o ano novo de 1991, mexendo na linguagem ABC, linguagem que tinha contado com a sua participação aquando do seu desenvolvimento. No começo de 1991, Van Rossum já havia feito uma especificação da linguagem Python bastante próxima da especificação corrente.

Hoje a linguagem Python é utilizada por milhares de pessoas em todo o mundo, sendo sustentada por uma fundação, a CNRI, e por um sem número de voluntários de várias nacionalidades, que unidos via Internet, formaram a Python Software Activity (PSA). Neste momento foi proposta a criação de um movimento chamado Python Consortium que tem por objectivo fomentar a linguagem, e dá-la a conhecer a empresas e instituições de ensino.

Características do Python Apesar de sua sintaxe simples e clara, Python oferece os seguintes recursos disponíveis também em linguagens mais complicadas como Java e C++:

• programação orientada a objectos (incluindo herança múltipla, conceito apenas parcialmente presente em Java);

• excepções, um moderno mecanismo para o tratamento de erros;

• módulos, uma forma inteligente de aceder, organizar e reutilizar código;

• recolha de lixo automática, sistema que elimina os erros causados pelo acumular de dados inúteis na memória do computador (característica presente também em Java, mas não em C++);

Page 9: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Introdução

9

• recursos avançados de manipulação de textos, listas e outras estruturas de dados

• possibilidade de executar o mesmo programa sem modificações em várias plataformas de hardware e sistemas operacionais (uma virtude de Java, mas difícil de se conseguir em C++);

• portabilidade, pode ser executada nos mais variados sistemas operativos (Unix, Windows, DOS, Mac, Os/390, OS/2 e Amiga).

Librarias do Python Como no Java, o Python possui uma grande quantidade de importantes librarias. Algumas destas librarias são cruciais para a flexibilidade que o Python oferece aos programadores. Algumas das mais importantes livrarias são:

• sys – permite o acesso a alguns estados do interpretador do Python.

• types – constantes para as “builtin types” .

• traceback – apoio para examinar a pilha de chamada “call stack” (muito útil para “debugging”).

• pickle – converte objectos do Python para ou a partir de fluxos de bytes (“byte streams”) portáteis

• shelve – armazenamento de objectos do Python

• copy – operações de cópia para os objectos.

• marshal – conversões de fluxos de dados “byte stream”

• __builtin__ - acesso a todos os identificadores “builtin” do Python.

• __main__ - o nível de topo do objecto.

• string – manipulação de string.

• egex – suporte das expressões regulares.

• regsub – substituição e divisão das expressões regulares básicas.

• struct – conversão das estruturas (structs) em C para strings.

• math – funções e constantes matemáticas.

• rand – gerador de números aleatórios.

• array – implementação eficiente de arrays.

• os - API portátil para sistemas operativos.

• time – funções relacionadas com a hora e a data.

• tempfile – geração de ficheiros temporários.

• signal – acesso a sinais POSIX.

Page 10: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

10

• posix – acesso às chamadas dos sistema POSIX.

• pwd – acesso às rotinas de acesso a ficheiros password em UNIX.

• pdb – linha de comando para debugger.

• grep – capacidade de procura em ficheiros.

• urllib – abre um URL usando sockets.

• httplib – protocolo HTTP.

• ftplib – protocolo FTP.

• gopherlib - protocolo GOPHER.

• nntplib - protocolo NNTP.

• htmllib - parser de HTML.

• audioop – manipulação de áudio.

• imageop – manipulação de imagens.

• jpeg – acesso a ficheiros em formato JPEG.

• Tkinter - Python GUI API standard.

Comparação com outras linguagens

Java Os programas em Python são geralmente mais lentos que os programas em Java, mas têm também um período de desenvolvimento muito menor. O tempo que demora a desenvolver um programa em Python é em média 3-5 vezes mais curto que o mesmo programa em Java. Esta diferença pode ser atribuída aos dados de alto nível introduzidos no Python e à sua escrita dinâmica. Por exemplo, um programador de Python, não precisa de perder tempo na declaração do tipo de argumentos ou na declaração das variáveis, mas devido à sua escrita em run-time, o run-time no Python tem que trabalhar mais que o do Java o que o torna mais lento.

Por estas razões o Python pode-se caracterizar como uma linguagem de “ ligação (glue)” , enquanto que o Java caracteriza-se como uma linguagem de baixo nível. De facto as duas fazem uma excelente combinação, os componentes podem ser desenvolvidos em Java e combinados de maneira a formar aplicações em Python.

JavaScript O modelo base de objectos do Python é muito parecido com o do JavaScript. Como o JavaScript, (e diferente do Java), o Python permite uma programação com funções simples e variáveis sem serem declaradas. Contudo para o JavaScript é tudo, enquanto que o Python permite a escrita de programas muito maiores e uma melhor reutilização de código, através do estilo de programação orientada a objecto onde as classes e a herança têm um papel preponderante.

Page 11: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Introdução

11

Perl O Python e o Perl têm uma base muito similar, têm muitas características semelhantes, mas têm uma filosofia diferente. O Perl está mais virado para permitir tarefas mais comuns orientadas para a aplicação. O Python por sua vez tenta debruçar-se mais em apoiar as metodologias de programação mais comuns como o desígnio das estruturas de dados e a programação orientada a objecto. O Phyton está muito próximo do Perl, mas raramente lhe ganha no seu domínio original. No entanto o Python tem uma boa aplicação para além do domínio do Perl.

Tcl Como o Python, o Tcl é usado como uma linguagem de extensão entre aplicações, bem como uma simples linguagem de programação. Contudo, o Tcl, guarda todos os tipos de dados como strings o que o torna muito limitado no tratamento de estruturas de dados. Além disso o tempo de execução do Tcl, é muito maior que o do Python. As características do Tcl não permitem que sejam escritos programas muito extensos. Por isso uma aplicação grande que use o Tcl, geralmente contém extensões escritas em C ou C++, que são específicas para a dada aplicação, uma aplicação equivalente desenvolvida em Python pode ser toda escrita em “Python puro” . Claro que, puro desenvolvimento em Python é muito mais rápido que ter que escrever e fazer o “debug” de um componente em C ou C++.

C++ Tudo o que foi dito para o Java , também pode ser aplicado ao C++, com a diferença de o tempo de desenvolvimento de C++ em relação o Python ser 5-10 vezes superior em vez de 3-5 vezes superior para o Java. Esta grande diferença sugere que, o que um programador de Python faria em 2 meses, levaria um ano a ser feito por dois programadores de C++.

Empresas/Instituições que usam o Python Existem várias empresas/instituições que já usam o Python em alguns dos seus mais arrojados projectos. por exemplo:

• RedHat;

• eGroups.com,;

• Google;

• InfoSeek;

• Real Networks – teste de RealMedia Client;

• Nortel Inc – projectos ChartWare, WebBook e WebTrack;

• Xerox Parc – projecto ILU (Inter Language Unification);

Page 12: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

12

• IBM – controlo e testes de ferramentas para a Internet;

• NASA John Space Center – Sistema de Planeamento Integrado;

• Telescópio Hubble - Advanced Camera for Surveys Projects;

• Walt Disney Imagineering;

• Greenpeace.

Page 13: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

O Interpretador do Python

13

OO II nntteerr pprr eettaaddoorr ddoo PPyytthhoonn

Page 14: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

14

O Interpretador do Python Vamos mostrar como usar o interpretador numa máquina Unix

O interpretador é frequentemente instalado como ‘ /usr/local/bin/python’ nas máquinas em que é disponibilizado. Se se adicionar ‘ /usr/local/bin’ ao caminho de busca (search path) da shell de seu Unix torna-se possível iniciá-lo digitando :

pyt hon

na shell.

Digitando um caracter EOF() (Cont r ol - D on Unix, Cont r ol - Z no DOS ou Windows) directamente no prompt, força o interpretador a sair com status de saída zero. Se isso não funcionar, pode-se sair do interpretador através da digitação do seguinte: ‘ i mpor t sys; sys. exi t ( ) ’ .

As características de edição de linha não são muito sofisticadas. Sobre Unix, pode-se instalar a biblioteca readline da GNU, que adiciona facilidades mais elaboradas de edição e histórico de comandos. Sem esta biblioteca apenas se poderá usar o backspace para remover caracteres da linha corrente.

O interpretador trabalha de forma semelhante a uma shell de Unix:

• quando disparado com a saída padrão conectada a uma consola de terminal (tty device), ele lê e executa comandos interactivamente;

• quando disparado com um nome de arquivo como parâmetro ou com redireccionamento da entrada padrão para um arquivo, o interpretador irá ler e executar o script contido em tal arquivo.

Uma terceira forma de disparar o interpretador é ‘python -c command [ ar g] . . . ’ , que executa o(s) comando(s) especificados na posição command, analogamente a opção de shell -c. Considerando que comandos Python possuem frequentemente espaços em branco (ou outros caracteres que sejam especiais para a shell) é aconselhável que o comando especificado em command esteja dentro de aspas.

Quando um arquivo de script é utilizado, às vezes é útil ser capaz de executá-lo para logo em seguida entrar em modo interactivo. Este efeito pode ser obtido pela adição do parâmetro -i antes do nome do script.

Passar Argumentos O nome do script e subsequentes parâmetros da linha de comando da shell são acessíveis ao próprio script através da variável sys. ar gv , que é uma lista de strings. Essa lista tem sempre pelo menos um elemento; quando nenhum script ou parâmetro forem passados para o interpretador, sys. ar gv[ 0] será uma lista vazia. Quando o nome

do script for ’ - ’ ( significando entrada padrão), o conteúdo de sys. ar gv[ 0] será ’ - ’ . Quando for utilizado -c command, sys. ar gv[ 0] conterá ’ - c ’ . Opções

Page 15: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

O Interpretador do Python

15

especificadas após -c command não serão consumidas pelo interpretador mas serão armazenadas em sys. ar gv .

Modo Interactivo Quando os comandos são lidos a partir da consola (tty), diz-se que o interpretador está em modo interativo. Nesse modo ele requisita por um próximo comando através do prompt primário, tipicamente três sinais de “maior que” (‘>>> ’ ); para linhas de continuação do comando corrente, o prompt secundário por defeito são três pontos (‘ . . . ’ ).

O interpretador imprime uma mensagem de boas vindas, informando a sua versão e uma nota legal de copyright antes de oferecer o primeiro prompt, ex.:

pyt hon

Pyt hon 1. 5. 2b2 ( #1, Feb 28 1999, 00: 02: 06) [ GCC 2. 8. 1] on sunos5

Copyr i ght 1991- 1995 St i cht i ng Mat hemat i sch Cent r um, Amst er dam

>>>

Linhas de continuação são necessárias em construções multi-linha. Como por exemplo este comando if:

>>> o_mundo_eh_pl ano = 1

>>> i f o_mundo_eh_pl ano:

. . . pr i nt " Cui dado par a não cai r f or a del e! "

. . .

Cui dado par a não cai r f or a del e!

O Interpretador e o seu Ambiente

Tratamento de Erros Quando ocorre um erro, o interpretador imprime uma mensagem de erro e a situação da pilha (daqui em diante stack trace). No modo interactivo, retorna-se ao prompt primário; quando a entrada vem de um arquivo, o interpretador aborta sua execução com status de erro diferente de zero após imprimir o stack trace (Excepções tratadas por um except num bloco t r y não são consideradas erros neste contexto). Alguns erros são incondicionalmente fatais e causam a saída com status diferente de zero; isto se aplica a inconsistências internas e alguns casos de exaustão de memória. Todas as mensagens de erro são escritas na saída de erros padrão (standard error), enquanto que a saída dos demais comandos é direccionada para a saída padrão.

Ao teclar num o caracter de interrupção (tipicamente Control-C ou DEL) no prompt primário ou secundário cancela a entrada de dados corrente e retorna-se ao prompt primário. Provocando uma interrupção enquanto um comando está em execução levanta a excepção Keyboar dI nt er r upt , a qual pode ser tratada em um bloco t r y .

Page 16: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

16

Scripts executáveis em Python Em sistemas UnixBSD, scripts Python podem ser transformados em executáveis, como shell scripts, pela inclusão do cabeçalho:

#! / usr / bi n/ env pyt hon

(Assumindo que o interpretador foi incluído do caminho de busca do usuário (PATH)) e que o script tenha a permissão de acesso habilitada para execução. O ‘#!’ deve estar no início do arquivo . Atenção pois o caracter ‘#’ designa comentários em Python.

O Arquivo de inicialização para Modo Interactivo Quando se utiliza Python interactivamente, pode ser útil adicionar uma série de comandos a serem executados por defeito antes de cada sessão de utilização do interpretador. Isto pode ser obtido pela configuração da variável de ambiente PYTHONSTARTUP para indicar o nome do arquivo script que contém o script de inicialização.

Essa característica assemelha-se aos arquivos ‘ .profile’ dos shells Unix.

O arquivo só é processado em sessões interactivas, nunca quando o Python lê comandos de um script especificado como parâmetro, nem tão pouco quando ‘ /dev/tty’ é especificado como a fonte de leitura de comandos (caso contrário iria-se comportar como uma sessão interactiva). O script de inicialização é executado no mesmo contexto em que os comandos da sessão interactiva serão executados, sendo assim, os objectos definidos e módulos importados podem ser utilizados sem qualificação durante a sessão interactiva. É possível também redefinir os prompts sys.ps1 e sys.ps2 através deste arquivo.

Se for necessário ler um script adicional de inicialização a partir do directório corrente, isso pode ser programado a partir do script de inicialização global, ex.: ‘ i f

os. pat h. i sf i l e( ’ . pyt honr c. py’ ) : execf i l e( ’ . pyt honr c. py’ ) ’ . Para se utilizar o script de inicialização noutro script, deve-se fazer da seguinte maneira:

i mpor t os

f i l ename = os. envi r on. get ( ’ PYTHONSTARTUP’ )

i f f i l ename and os. pat h. i s f i l e( f i l ename) :

execf i l e( f i l ename)

Page 17: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Uma introdução informal ao Python

17

UUmmaa iinnttrr oodduuççããoo iinnffoorr mmaall aaoo PPyytthhoonn

Page 18: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

18

Uma introdução informal ao Python Nos exemplos seguintes, pode-se distinguir a entrada da saía pela presença ou ausência dos prompts (‘>>> ’ e ‘ . . . ’ ): para repetir o exemplo deve-se digitar tudo após o prompt, quando o mesmo aparece; linhas que não começarem com o prompt são na verdade as saídas geradas pelo interpretador.

Observe que existe um segundo prompt indicando a linha de continuação de um comando com múltiplas linhas, o qual pode ser encerrado pela digitação de um linha em branco.

Muitos dos exemplos neste manual, até mesmo aqueles digitados interactivamente, incluem comentários. Comentários em Python são delimitados pelo caracter ‘#’ , e estendem-se até o final da linha. Um comentário pode aparecer no início da linha, depois de um espaço em branco ou código, mas nunca dentro de uma string (literal).

O delimitar de comentário dentro de uma string é interpretado como o próprio caracter.

Alguns exemplos:

# pr i mei r o coment ár i o

SPAM = 1 # e esse é o segundo coment ár i o

# . . . e ai nda um t er cei r o !

STRI NG = " # Est e não é um coment ár i o. "

Utilizando o Python como uma calculadora Depois de iniciar o interpretador aguardar pelo prompt primário, ‘>>> ’ .

Números O interpretador actua como uma calculadora bem simples: pode-se digitar uma expressão e o resultado será apresentado após a avaliação da expressão. A sintaxe da expressão é a usual: operadores +, - , * e / funcionam da mesma forma que nas outras linguagens tradicionais (por exemplo, Pascal ou C); parênteses podem ser usados para definir agrupamentos. Por exemplo:

>>> 2+2

4

>>> # I sso é um coment ár i o

. . . 2+2

4

>>> 2+2 # e um coment ár i o na mesma l i nha de um comando

4

>>> ( 50- 5* 6) / 4

5

>>> # Di v i são i nt ei r a r et or na com ar r edondament o par a base

. . . 7/ 3

Page 19: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Uma introdução informal ao Python

19

2

>>> 7/ - 3

- 3

Como em C, o sinal de igual (‘=’ ) é utilizado para atribuição de um valor a uma variável. O valor da atribuição não é escrito:

>>> wi dt h = 20

>>> hei ght = 5* 9

>>> wi dt h * hei ght

900

Um valor pode ser atribuído a diversas variáveis simultaneamente: >>> x = y = z = 0 # Zer o x, y e z

>>> x

0

>>> y

0

>>> z

0

Operadores com operandos de diferentes tipos convertem o inteiro para ponto-flutuante: >>> 4 * 2. 5 / 3. 3

3. 0303030303

>>> 7. 0 / 2

3. 5

Números complexos também são suportados; números imaginários são escritos com o sufixo ‘ j’ ou ‘J’ . Números complexos com parte real não nula são escritos como ‘ (real+imagj)’ , ou podem ser criados pela chamada de função ‘complex(real, imag)’ .

>>> 1j * 1J

( - 1+0j )

>>> 1j * compl ex( 0, 1)

( - 1+0j )

>>> 3+1j * 3

( 3+3j )

>>> ( 3+1j ) * 3

( 9+3j )

>>> ( 1+2j ) / ( 1+1j )

( 1. 5+0. 5j )

Números complexos são sempre representados por dois números ponto-flutuante, a parte real e a parte imaginária.

Para extrair as partes de um número z, utilize z.real e z.imag.

>>> a=1. 5+0. 5j

Page 20: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

20

>>> a. r eal

1. 5

>>> a. i mag

0. 5

As funções de conversão para ponto-flutuante e inteiro (float(), int() e long()) não funcionam para números complexos pois não existe maneira correcta de converter um número complexo para um número real. Pode utilizar-se abs(z) para obter sua magnitude (como ponto-flutuante) ou z.real para obter sua parte real.

>>> a=1. 5+0. 5j

>>> f l oat ( a)

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1, i n ?

TypeEr r or : can’ t conver t compl ex t o f l oat ; use e. g. abs( z)

>>> a. r eal

1. 5

>>> abs( a)

1. 58113883008

No modo interactivo, a última expressão a ser impressa é atribuída à variável . Isso significa que ao utilizar Python como uma calculadora, é muitas vezes mais fácil prosseguir com os cálculos da seguinte forma:

>>> t ax = 17. 5 / 100

>>> pr i ce = 3. 50

>>> pr i ce * t ax

0. 61249999999999993

>>> pr i ce + _

4. 1124999999999998

>>> r ound( _, 2)

4. 1100000000000003

Essa variável especial deve ser tratada somente para leitura pelo usuário. Nunca lhe atribua explicitamente um valor, caso contrário, estaria a ser criada uma outra variável (homónima) independente, que mascararia o comportamento mágico da variável especial.

Strings Além de números, o Python também pode manipular strings, que podem ser expressas de diversas formas. Elas podem ser delimitadas por plicas ou aspas:

>>> ’ spam eggs’

’ spam eggs’

>>> ’ doesn\ ’ t ’

" doesn’ t "

>>> " doesn’ t "

Page 21: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Uma introdução informal ao Python

21

" doesn’ t "

>>> ’ " Yes, " he sai d. ’

’ " Yes, " he sai d. ’

>>> " \ " Yes, \ " he sai d. "

’ " Yes, " he sai d. ’

>>> ’ " I sn\ ’ t , " she sai d. ’

’ " I sn\ ’ t , " she sai d. ’

Strings que contém mais de uma linha podem ser construídas de diversas maneiras. Terminadores de linha podem ser colocados na string com barras invertidas, ex.:

ol a = " Est a é uma st r i ng l onga cont endo\ n\

di ver sas l i nhas de t ext o com se f az em C. \ n\

Obser ve que os espaços em br anco no i ni c i o da l i nha são \

s i gni f i cat i vos. \ n"

pr i nt ol a

que produziria o seguinte resultado: Est a é uma st r i ng l onga cont endo

di ver sas l i nhas de t ext o com se f az em C.

Obser ve que os espaços em br anco no i ni c i o da l i nha são si gni f i cat i vos.

Ou, strings podem ser delimitadas por pares de aspas tríplices: " ou ’ ’ ’ . Neste caso não é necessário embutir terminadores de linha, pois o texto da string será tratado verbatim.

pr i nt " " "

Usage: t hi ngy [ OPTI ONS]

- h Di spl ay t hi s usage message

- H host name Host name t o connect t o

" " "

produz a seguinte saída: Usage: t hi ngy [ OPTI ONS]

- h Di spl ay t hi s usage message

- H host name Host name t o connect t o

O interpretador imprime o resultado de operações sobre strings da mesma forma que as strings são formatadas na digitação: dentro de aspas, e com caracteres especiais embutidos em escape sequences, para mostrar seu valor com precisão. A string será delimitada por aspas duplas se ela contém um único caracter de aspas simples e nenhum de aspas duplas, caso contrário a string será delimitada por aspas simples. ( O comando pr i nt , descrito posteriormente, pode ser utilizado para escrever strings sem aspas ou escape sequences.).

Strings podem ser concatenadas (coladas) com o operador +, e repetidas com * : >>> wor d = ’ Hel p’ + ’ A’

>>> wor d

’ Hel pA’

Page 22: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

22

>>> ’ <’ + wor d* 5 + ’ >’

’ <Hel pAHel pAHel pAHel pAHel pA>’

Duas strings literais justapostas são automaticamente concatenadas; a primeira linha do exemplo anterior poderia ter sido escrita como ‘wor d = ’ Hel p’ ’ A’ ’ ; isso funciona somente com strings literais, não com expressões arbitrárias:

>>> i mpor t st r i ng

>>> ’ st r ’ ’ i ng’ # <- Thi s i s ok

’ st r i ng’

>>> st r i ng. st r i p( ’ s t r ’ ) + ’ i ng’ # <- Thi s i s ok

’ st r i ng’

>>> st r i ng. st r i p( ’ s t r ’ ) ’ i ng’ # <- Thi s i s i nval i d

Fi l e " <st di n>" , l i ne 1

st r i ng. st r i p( ’ s t r ’ ) ’ i ng’

ˆ

Synt axEr r or : i nval i d synt ax

Strings podem ser indexadas; como no C, o primeiro índice da string é o 0. Não existe um tipo separado para caracteres; um caracter é simplesmente uma string unitária. Assim como na linguagem Icon, substrings podem ser especificadas através da notação slice (N.d.T: fatiar): dois índices separados por dois pontos.

>>> wor d[ 4]

’ A’

>>> wor d[ 0: 2]

’ He’

>>> wor d[ 2: 4]

’ l p’

Ao contrário do C, strings não podem ser alteradas em Python. Atribuir para uma posição (índice) dentro de uma string resultará em erro:

>>> wor d[ 0] = ’ x ’

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1, i n ?

TypeEr r or : obj ect doesn’ t suppor t i t em assi gnment

>>> wor d[ : 1] = ’ Spl at ’

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1, i n ?

TypeEr r or : obj ect doesn’ t suppor t sl i ce assi gnment

Entretanto, criar uma nova string com o conteúdo combinado é fácil e eficiente: >>> ’ x’ + wor d[ 1: ]

’ xel pA’

>>> ’ Spl at ’ + wor d[ 4]

’ Spl at A’

Page 23: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Uma introdução informal ao Python

23

Índices de slice possuem valores por defeito úteis; o primeiro índice se omitido possui valor por defeito 0, o segundo possui valor por defeito igual ao tamanho da string.

>>> wor d[ : 2] # Os doi s pr i mei r os car act er es

’ He’

>>> wor d[ 2: ] # Todos menos os doi s pr i mei r os car act er es

’ l pA’

Índices de slice degenerados são tratados “graciosamente” (N.d.T: este termo indica robustez no tratamento de erros): um índice muito maior que o comprimento é trocado pelo comprimento, um limitante superior que seja menor que o limitante inferior produz uma string vazia como resultado.

>>> wor d[ 1: 100]

’ el pA’

>>> wor d[ 10: ]

’ ’

>>> wor d[ 2: 1]

’ ’

Índices podem ser números negativos, para iniciar a contagem a partir da direita ao invés da esquerda. Por exemplo:

>>> wor d[ - 1] # O úl t i mo car act er

’ A’

>>> wor d[ - 2] # O penúl t i mo car act er

’ p’

>>> wor d[ - 2: ] # Os doi s ´ ul t i mos car act er es

’ pA’

>>> wor d[ : - 2] # Todos menos os doi s úl t i mos car act er es

’ Hel ’

Note-se que -0 é o mesmo que 0, logo neste caso não se conta a partir da direita! >>> wor d[ - 0] # ( - 0 == 0)

’ H’

Intervalos fora dos limites da string são truncados, mas não tente isso em indexações com um único índice (que não seja um slice):

>>> wor d[ - 100: ]

’ Hel pA’

>>> wor d[ - 10] # er r or

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1

I ndexEr r or : st r i ng i ndex out of r ange

A melhor maneira de se lembrar como os slices funcionam é pensar nos índices como ponteiros para os espaços entre caracteres, onde a beirada esquerda do primeiro caracter é

Page 24: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

24

0. Logo a beirada direita do último caracter de uma string de comprimento n tem índice n, por exemplo:

+- - - +- - - +- - - +- - - +- - - +

| H | e | l | p | A |

+- - - +- - - +- - - +- - - +- - - +

0 1 2 3 4 5

- 5 - 4 - 3 - 2 - 1

A primeira fileira de números indica a posição dos índices 0..5 na string; a segunda fileira indica a posição dos respectivos índices negativos. Um slice de i até j consiste em todos os caracteres entre as beiradas i e j, respectivamente.

Para índices positivos, o comprimento do slice é a diferença entre os índices, se ambos estão dentro dos limites da string, ex, o comprimento de wor d[ 1: 3] é 2.

A função interna (N.d.T: interna == built-in) l en( ) devolve o comprimento de uma string:

>>> s = ’ super cal i f r agi l i s t i cexpi al i doci ous’

>>> l en( s)

34

Strings Unicode A partir de Python 2.0 um novo tipo foi introduzido: o objecto Unicode. Este objecto pode ser usado para armazenar e manipular dados Unicode e se integra bem aos demais objectos strings pré existentes de forma a realizar auto-conversões quando necessário.

O Unicode tem a vantagem de prover um único número ordinal para cada caracter usado em textos modernos ou antigos. Previamente, havia somente 256 números ordinais. Logo, mapeamentos entre conjuntos de caracteres e os 256 números ordinais precisavam ser indexados por códigos de página. Isso levou a uma enorme confusão especialmente no âmbito da internacionalização (tipicamente escrito como ‘ i 18n’ – ‘ i ’ + 18 caracteres + ‘n’ ) de software. Unicode resolve esses problemas ao definir um único código de página para todos os conjuntos de caracteres.

Criar strings Unicode em Python é tão simples quanto criar strings normais: >>> u’ Hel l o Wor l d ! ’

u’ Hel l o Wor l d ! ’

O pequeno ‘u’ antes das aspas indica a criação de uma string Unicode . Se você desejar incluir caracteres especiais na string, você pode fazê-lo através da codificação Python Unicode-Escape.

>>> u’ Hel l o\ u0020Wor l d ! ’

u’ Hel l o Wor l d ! ’

O código de escape \ u0020 indica a inserção do caracter Unicode com valor ordinal 0x0020 (o espaço em branco) na posição determinada.

Page 25: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Uma introdução informal ao Python

25

Os outros caracteres são interpretados através de seus respectivos valores ordinais directamente para os valores ordinais em Unicode.

Para experts, existe ainda um modo cru (N.d.T: sem processamento de caracteres escape) da mesma forma que existe para strings normais. Basta prefixar a string com ’ur’ para utilizar a codificação Python Raw-Unicode-Escape. Só será aplicado a conversão \ uXXXX se houver um número ímpar de barras invertidas antes do escape ’u’ .

>>> ur ’ Hel l o\ u0020Wor l d ! ’

u’ Hel l o Wor l d ! ’

>>> ur ’ Hel l o\ \ u0020Wor l d ! ’

u’ Hel l o\ \ \ \ u0020Wor l d ! ’

O modo cru (N.d.T: raw) é muito útil para evitar excesso de barras invertidas em expressões regulares.

Além dessas codificações padrão, Python oferece um outro conjunto de maneiras de se criar strings Unicode sobre uma codificação padrão.

A função interna uni code( ) provê acesso a todos os Unicode codecs registrados (COders and DECoders).

Alguns dos mais conhecidos codecs são : Latin-1, ASCII, UTF-8, and UTF-16. Os dois últimos são codificações de tamanho variável para armazenar cada caracter Unicode em um ou mais bytes. A codificação por defeito é ASCII, que trata normalmente caracteres no intervalo de 0 a 127 mas rejeita qualquer outro com um erro. Quando uma string Unicode é impressa, escrita em arquivo ou convertida por st r ( ) , a codificação padrão é utilizada.

>>> u" abc"

u’ abc’

>>> st r ( u" abc" )

’ abc’

>>> u" ¨ a¨ o¨ u"

u’ \ xe4\ xf 6\ xf c ’

>>> st r ( u" ¨ a¨ o¨ u" )

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1, i n ?

Uni codeEr r or : ASCI I encodi ng er r or : or di nal not i n r ange( 128)

Para se converter uma string Unicode em uma string 8-bits usando uma codificação específica, basta invocar o método encode( ) de objectos Unicode passando como parâmetro o nome da codificação destino. É preferível utilizar nomes de codificação em letras minúsculas.

>>> u" ¨ a¨ o¨ u" . encode( ’ ut f - 8’ )

’ \ xc3\ xa4\ xc3\ xb6\ xc3\ xbc’

Também pode ser utilizada a função uni code( ) para efectuar a conversão de uma string em outra codificação.

Page 26: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

26

Neste caso, o primeiro parâmetro é a string a ser convertida e o segundo o nome da codificação almejada. O valor de retorno da função é a string na nova codificação.

>>> uni code( ’ \ xc3\ xa4\ xc3\ xb6\ xc3\ xbc’ , ’ ut f - 8’ )

u’ \ xe4\ xf 6\ xf c ’

Listas Python possui diversas estruturas de dados nativas, utilizadas para agrupar outros valores. A mais versátil delas é a lista (list), que pode ser escrita como uma lista de valores separados por vírgula e entre colchetes. Mais importante, os valores contidos na lista não precisam ser do mesmo tipo.

>>> a = [ ’ spam’ , ’ eggs’ , 100, 1234]

>>> a

[ ’ spam’ , ’ eggs’ , 100, 1234]

Da mesma forma que índices de string, índices de lista começam do 0, listas também podem ser concatenadas e sofrer o operador de slice.

>>> a[ 0]

’ spam’

>>> a[ 3]

1234

>>> a[ - 2]

100

>>> a[ 1: - 1]

[ ’ eggs’ , 100]

>>> a[ : 2] + [ ’ bacon’ , 2* 2]

[ ’ spam’ , ’ eggs’ , ’ bacon’ , 4]

>>> 3* a[ : 3] + [ ’ Boe! ’ ]

[ ’ spam’ , ’ eggs’ , 100, ’ spam’ , ’ eggs’ , 100, ’ spam’ , ’ eggs’ , 100, ’ Boe! ’ ]

Ao contrário das strings, que são imutáveis, é possível mudar elementos individuais da lista:

>>> a

[ ’ spam’ , ’ eggs’ , 100, 1234]

>>> a[ 2] = a[ 2] + 23

>>> a

[ ’ spam’ , ’ eggs’ , 123, 1234]

Atribuição à fatias (slices) é possível, e isso pode até alterar o tamanho da lista: >>> # Repl ace some i t ems:

. . . a[ 0: 2] = [ 1, 12]

>>> a

[ 1, 12, 123, 1234]

>>> # Remove some:

Page 27: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Uma introdução informal ao Python

27

. . . a[ 0: 2] = [ ]

>>> a

[ 123, 1234]

>>> # I nser t some:

. . . a[ 1: 1] = [ ’ bl et ch’ , ’ xyzzy’ ]

>>> a

[ 123, ’ bl et ch’ , ’ xyzzy’ , 1234]

>>> a[ : 0] = a # I nser t ( a copy of ) i t sel f at t he begi nni ng

>>> a

[ 123, ’ bl et ch’ , ’ xyzzy’ , 1234, 123, ’ bl et ch’ , ’ xyzzy’ , 1234]

A função interna len() também se aplica às listas: >>> l en( a)

8

É possível criar listas que contêm outras listas, por exemplo: >>> q = [ 2, 3]

>>> p = [ 1, q, 4]

>>> l en( p)

3

>>> p[ 1]

[ 2, 3]

>>> p[ 1] [ 0]

2

>>> p[ 1] . append( ’ xt r a’ ) # See sect i on 5. 1

>>> p

[ 1, [ 2, 3, ’ xt r a’ ] , 4]

>>> q

[ 2, 3, ’ x t r a’ ]

Primeiros passos em direcção à programação Naturalmente, pode-se utilizar Python para tarefas mais complicadas do que somar dois números. A título de exemplificação, pode-se escrever o início da sequência de Fibonacci assim:

>>> # Ser i e de Fi bonacci :

. . . # A soma de doi s el ement os def i ne o pr óxi mo

. . . a, b = 0, 1

>>> whi l e b < 10:

. . . pr i nt b

. . . a, b = b, a+b

. . .

Page 28: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

28

1

1

2

3

5

8

Este exemplo introduz diversas características ainda não mencionadas:

• A primeira linha contém uma atribuição múltipla: as variáveis a e b simultaneamente recebem os novos valores 0 e 1. Na última linha há outro exemplo de atribuição múltipla demonstrando que expressões do lado direito são sempre avaliadas primeiro, antes da atribuição. As expressões do lado direito são avaliadas da esquerda para a direita.

• O ciclo while executa enquanto a condição (aqui: b < 10) permanecer verdadeira. No Python, como no C, qualquer valor inteiro não nulo á considerado verdadeiro (valor true), zero tem o valor false. A condição pode ser ainda uma lista ou uma string, na verdade qualquer sequência; qualquer coisa com comprimento não nulo tem o valor true e sequências vazias têm valor false. O teste utilizado no exemplo é uma simples comparação. Os operadores padrão para comparação são os mesmos do C: < (menor que), > (maior que), == (igual), <= (menor ou igual), >= (maior ou igual) e != (diferente).

• O corpo do ciclo é identado: identação em Python é a maneira de agrupar comandos. O Python (ainda!) não possui facilidades automáticas de edição de linha. Na prática quando se quiser preparar scrips mais complexos, geralmente tem que se usar um editor de texto. A maioria dos editores de texto possuem facilidades de identação automática. Quando comandos compostos forem alimentados ao interpretador interactivamente, devem ser encerrados por uma linha em branco (já que o parser não tem como adivinhar qual é a última linha do comando). De notar que toda linha de um mesmo bloco de comandos deve possuir a mesma identação.

O comando pr i nt escreve o valor da expressão dada. O pr i nt aceita múltiplas expressões e strings. Strings são impressas sem aspas, um espaço é inserido entre itens de forma a formatar o resultado assim:

>>> i = 256* 256

>>> pr i nt ’ The val ue of i i s’ , i

The val ue of i i s 65536

Uma vírgula ao final evita a quebra de linha: >>> a, b = 0, 1

>>> whi l e b < 1000:

. . . pr i nt b,

. . . a, b = b, a+b

. . .

Page 29: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Uma introdução informal ao Python

29

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

Page 30: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

30

Page 31: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Ferramentas de controle de fluxos

31

FFeerr rr aammeennttaass ddee ccoonnttrr oollee ddee ff lluuxxooss

Page 32: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

32

Ferramentas de controle de fluxos Além do whi l e recém apresentado, Python possui as estruturas usuais de controle de fluxo conhecidas em outras linguagens, com algumas variações:

Construção do if Provavelmente uma das mais conhecidas construções é o i f . Por exemplo:

>>> x = i nt ( r aw_i nput ( " Por f avor ent r e com um numer o: " ) )

>>> i f x < 0:

. . . x = 0

. . . pr i nt ’ Negat i vo mudou par a zer o’

. . . el i f x == 0:

. . . pr i nt ’ Zer o’

. . . el i f x == 1:

. . . pr i nt ’ Um’

. . . el se:

. . . pr i nt ’ Mai s ’

. . .

Pode haver zero ou mais secções el i f . A secção el se é opcional. A palavra-chave ‘el i f ’ ´e uma abreviação para ‘else if’ , e é útil para evitar identação excessiva. Uma sequência i f . . . el i f . . . el i f . . . substitui as construções swi t ch e case encontradas nas outras linguagens.

Construção do for A construção do f or em Python difere um pouco do que se está acostumado em C ou Pascal. Ao invés de se iterar sobre progressões aritméticas (como em Pascal), ou fornecer ao usuário a habilidade de definir tanto o passo da iteração quanto a condição de parada (como no C), o f or do Python itera sobre os itens de uma sequência (ex.: uma lista ou uma string), na ordem em que aparecem na sequência. Por exemplo :

>>> # Medi ndo al gumas st r i ngs:

. . . a = [ ’ gat o’ , ’ j anel a’ , ’ l ei t e’ ]

>>> f or x i n a:

. . . pr i nt x, l en( x)

. . .

gat o 4

j anel a 6

l ei t e 5

Não é seguro modificar a sequência sobre a qual se baseia o ciclo da iteração (isto só pode acontecer se a sequência for mutável, isto é, uma lista). Se se precisar modificar a

Page 33: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Ferramentas de controle de fluxos

33

lista sobre a qual se está iterando, por exemplo, para duplicar itens seleccionados, você deve iterar sobre uma cópia da lista ao invés da própria. A notação slice é particularmente conveniente para isso:

>>> f or x i n a[ : ] : # f az uma cópi a da l i s t a i nt ei r a

. . . i f l en( x) > 6: a. i nser t ( 0, x)

. . .

>>> a

[ ’ def enest r ar ’ , ’ gat o’ , ’ j anel a’ , ’ def enest r ar ’ ]

A função range() Pare se poder iterar sobre sequências numéricas, a função interna r ange( ) é a resposta. Ela gera listas contendo progressões aritméticas, ex.:

>>> r ange( 10)

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

O ponto de parada fornecido nunca é gerado na lista; r ange( 10) gera uma lista com 10 valores, exactamente os índices válidos para uma sequência de comprimento 10. É possível iniciar o intervalo em outro número, ou alterar a razão da progressão:

>>> r ange( 5, 10)

[ 5, 6, 7, 8, 9]

>>> r ange( 0, 10, 3)

[ 0, 3, 6, 9]

>>> r ange( - 10, - 100, - 30)

[ - 10, - 40, - 70]

Para se iterar sobre os índices de uma sequência, deve-se combinar o r ange( ) com o l en( ) da seguinte forma:

>>> a = [ ’ Mar y’ , ’ had’ , ’ a’ , ’ l i t t l e’ , ’ l amb’ ]

>>> f or i i n r ange( l en( a) ) :

. . . pr i nt i , a[ i ]

. . .

0 Mar y

1 had

2 a

3 l i t t l e

4 l amb

Cláusulas break, continue e else em ciclos O br eak , como no C, quebra o laço mais interno de um f or ou whi l e.

O cont i nue , também emprestado do C, continua o próximo passo do ciclo mais interno.

Page 34: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

34

Os ciclos podem ter uma cláusula el se, que é executada sempre que o ciclo termina, quer quando se ciclo se encerra por exaustão da lista (no casodo f or ), quer quando a condição se torna falsa (no caso do whi l e), mas nunca quando o ciclo é encerrado por um br eak . Isto é exemplificado no próximo exemplo que procura números primos:

>>> f or n i n r ange( 2, 10) :

. . . f or x i n r ange( 2, n) :

. . . i f n % x == 0:

. . . pr i nt n, ’ equal s ’ , x, ’ * ’ , n/ x

. . . br eak

. . . el se:

. . . pr i nt n, ’ i s a pr i me number ’

. . .

2 i s a pr i me number

3 i s a pr i me number

4 equal s 2 * 2

5 i s a pr i me number

6 equal s 2 * 3

7 i s a pr i me number

8 equal s 2 * 4

9 equal s 3 * 3

Construção pass A construção pass não faz nada. Ela pode ser usada quando a sintaxe exige um comando mas a semântica do programa não requer nenhuma acção. Por exemplo:

>>> whi l e 1:

. . . pass # Busy- wai t par a i nt er r upção do t ecl ado

. . .

Funções A função que se segue escreve a série de Fibonacci até um limite arbitrário:

>>> def f i b( n) : # escr eve a ser i e de Fi bonacci at e n

. . . " Pr i nt a Fi bonacci ser i es up t o n"

. . . a, b = 0, 1

. . . whi l e b < n:

. . . pr i nt b,

. . . a, b = b, a+b

. . .

>>> # Agor a i nvoca a f unção que acabamos de def i ni r

. . . f i b( 2000)

Page 35: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Ferramentas de controle de fluxos

35

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

A palavra reservada def serve para definir uma função. Ela deve ser seguida do nome da função, da lista formal de parâmetros entre parênteses e dois pontos.

O corpo da função deve começar na linha seguinte e deve ser identado. Opcionalmente, a primeira linha do corpo da função pode ser uma string literal, cujo propósito é documentar a função. A essa string dá-se o nome de docstring.

Existem ferramentas que utilizam docstrings para produzir automaticamente documentação impressa, on-line, ou ainda permitir que o usuário navegue interactivamente pelo código. É uma boa prática incluir sempre docstrings nas funções.

A execução da função gera uma nova tabela de símbolos utilizada para as variáveis locais da função, mais precisamente, toda atribuição a variáveis dentro da função armazena o valor na tabela de símbolos local. Referências às variáveis são procuradas primeiramente na tabela local, depois na tabela de símbolos global e finalmente na tabela de símbolos interna (built-in). Portanto, não se pode atribuir directamente um valor a uma variável global dentro de uma função (a menos que se utilize a declaração gl obal antes), ainda que variáveis globais possam ser referenciadas livremente.

Os parâmetros reais (argumentos) de uma chamada da função são introduzidos na tabela de símbolos local da função chamada, portanto, os argumentos são passados por valor (onde valor é sempre uma referência para o objecto, não o valor do objecto). Quando uma função chama outra, uma nova tabela de símbolos é criada para tal chamada.

Uma definição da função introduz o nome da função na tabela de símbolos corrente. O valor do nome da função possui um tipo que é reconhecido pelo interpretador como uma função definida pelo usuário. Esse valor pode ser atribuído para outros nomes que também podem ser usados como funções. Esse mecanismo serve para renomear funções:

>>> f i b

<f unct i on obj ect at 10042ed0>

>>> f = f i b

>>> f ( 100)

1 1 2 3 5 8 13 21 34 55 89

Pode-se afirmar que f i b não é uma função, mas um procedimento. No Python, assim como no C, procedimentos são apenas funções que não retornam valores. Na verdade, falando tecnicamente, procedimentos retornam o valor None (é um nome interno). A escrita do valor None é supressa pelo interpretador se ele estiver sozinho. Para verificar isso basta:

>>> pr i nt f i b( 0)

None

É muito simples escrever uma função que retorna a lista da série de Fibonacci, ao invés de imprimi-la:

>>> def f i b2( n) :

. . . " Ret or na a l i s t a cont endo a ser i e de Fi bonacci at e n"

. . . r esul t = [ ]

Page 36: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

36

. . . a, b = 0, 1

. . . whi l e b < n:

. . . r esul t . append( b) # vej a abai xo

. . . a, b = b, a+b

. . . r et ur n r esul t

. . .

>>> f 100 = f i b2( 100) # i nvoca

>>> f 100 # escr eve r esul t ado

[ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

Este exemplo, como sempre, demonstra algumas características novas:

• A palavra-chave r et ur n termina a função retornando um valor. Se r et ur n não for seguido de nada, então retorna o valor None. Se a função chegar ao fim sem o uso explícito do r et ur n, então também será retornado o valor None.

• O comando r esul t . append( b) chama um método do objecto lista r esul t . Um método é uma função que pertence a um objecto e é chamada através de obj . met hodname, onde obj é um objecto qualquer, e met hodname é o nome de um método que foi definido pelo tipo do objecto. Tipos diferentes definem métodos diferentes. Sobretudo, métodos de diferentes tipos podem ser homónimos sem ambiguidade (é possível definir os seus próprios tipos de objectos e métodos, utilizando classes, como será discutido mais tarde neste tutorial). O método append( ) do exemplo é definido para todos objectos do tipo lista. Este método permite a adição de novos elementos à lista. Neste exemplo, equivale a ‘ r esul t = r esul t + [ b] ’ , só que append( ) é ainda é mais eficiente.

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

Parâmetros com valores por defeito Pode-se especificar um valor por defeito para um ou mais argumentos. Isso cria uma função que pode ser invocada com um número menor de argumentos do que quando foi definida, ex:

def ask_ok( pr ompt , r et r i es=4, compl ai nt =’ Yes or no, pl ease! ’ ) :

whi l e 1:

ok = r aw_i nput ( pr ompt )

i f ok i n ( ’ y ’ , ’ ye’ , ’ yes’ ) : r et ur n 1

i f ok i n ( ’ n’ , ’ no’ , ’ nop’ , ’ nope’ ) : r et ur n 0

r et r i es = r et r i es - 1

i f r et r i es < 0: r ai se I OEr r or , ’ r ef useni k user ’

pr i nt compl ai nt

Page 37: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Ferramentas de controle de fluxos

37

Essa função pode ser chamada de duas formas: ask ok( ’ Do you r eal l y want t o qui t ?’ ) ou como ask ok( ’ OK t o over wr i t e t he f i l e?’ , 2) .

Os valores por defeito são avaliados durante a definição da função, e pela finalidade da função definida:

i = 5

def f ( ar g = i ) : pr i nt ar g

i = 6

f ( )

irá imprimir 5.

Aviso impor tante: Valores por defeito são avaliados apenas uma vez. Isso faz diferença quando o valor por defeito é um objecto mutável como uma lista ou dicionário. Por exemplo, a função a seguir acumula os argumentos passados em chamadas subsequentes:

def f ( a, l = [ ] ) :

l . append( a)

r et ur n l

pr i nt f ( 1)

pr i nt f ( 2)

pr i nt f ( 3)

Isso irá imprimir: [ 1]

[ 1, 2]

[ 1, 2, 3]

Se não se quiser que o valor por defeito seja compartilhado entre chamadas subsequentes, pode-se reescrever a função:

def f ( a, l = None) :

i f l i s None:

l = [ ]

l . append( a)

r et ur n l

Parâmetros na forma Chave-Valor As funções também podem ser chamadas passando argumentos no formato chave-valor como ‘keyword = value’ . Por exemplo:

def par r ot ( vol t age, st at e=’ a st i f f ’ , act i on=’ voom’ , t ype=’ Nor wegi an Bl ue’ ) :

pr i nt " - - Thi s par r ot woul dn’ t " , act i on,

pr i nt " i f you put " , vol t age, " Vol t s t hr ough i t . "

pr i nt " - - Lovel y pl umage, t he" , t ype

pr i nt " - - I t ’ s" , s t at e, " ! "

poderia ser chamada em qualquer uma das seguintes maneiras:

Page 38: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

38

par r ot ( 1000)

par r ot ( act i on = ’ VOOOOOM’ , vol t age = 1000000)

par r ot ( ’ a t housand’ , s t at e = ’ pushi ng up t he dai s i es’ )

par r ot ( ’ a mi l l i on’ , ’ ber ef t of l i f e’ , ’ j ump’ )

porém, existem maneiras inválidas: par r ot ( ) # par âmet r o exi gi do f al t ando

par r ot ( vol t age=5. 0, ’ dead’ ) # par âmet r o não- chave- val or depoi s de

# par âmet r o chave- val or

par r ot ( 110, vol t age=220) # val or dupl i cado par a mesmo par âmet r o

par r ot ( act or =’ John Cl eese’ ) # par âmet r o desconheci do

Em geral, uma lista de argumentos tem que apresentar todos argumentos posicionais antes de qualquer um dos seus argumentos chave-valor, onde as chaves têm que ser escolhidas a partir dos nomes formais dos argumentos.

Não é importante se um dado argumento já possuía valor por defeito ou não. Nenhum argumento deve receber um valor mais do que uma única vez. Nomes de parâmetros formais correspondendo a argumentos posicionais não podem ser usados na forma chave-valor numa mesma chamada. O próximo exemplo ilustra essa limitação.

>>> def f unct i on( a) :

. . . pass

. . .

>>> f unct i on( 0, a=0)

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1, i n ?

TypeEr r or : keywor d par amet er r edef i ned

Quando o último parâmetro formal for * *name, ele irá armazenar todos os parâmetros efectivamente passados para a função, que não correspondiam a parâmetros formais. Isto pode ser combinado com o parâmetro formal *name que recebe a lista contendo todos argumentos posicionais que não correspondiam a parâmetros formais. O importante é que (*name deve ser declarado antes de **name.):

def cheeseshop( ki nd, * ar gument s, * * keywor ds) :

pr i nt " - - Do you have any" , k i nd, ’ ?’

pr i nt " - - I ’ m sor r y, we’ r e al l out of " , k i nd

f or ar g i n ar gument s: pr i nt ar g

pr i nt ’ - ’ * 40

f or kw i n keywor ds. keys( ) : pr i nt kw, ’ : ’ , keywor ds[ kw]

Poderia ser chamado assim: cheeseshop( ’ Li mbur ger ’ , " I t ’ s ver y r unny, s i r . " ,

" I t ’ s r eal l y ver y, VERY r unny, s i r . " ,

c l i ent =’ John Cl eese’ ,

shopkeeper =’ Mi chael Pal i n’ ,

Page 39: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Ferramentas de controle de fluxos

39

sket ch=’ Cheese Shop Sket ch’ )

e naturalmente produziria: - - Do you have any Li mbur ger ?

- - I ’ m sor r y, we’ r e al l out of Li mbur ger

I t ’ s ver y r unny, s i r .

I t ’ s r eal l y ver y, VERY r unny, si r .

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

c l i ent : John Cl eese

shopkeeper : Mi chael Pal i n

sket ch : Cheese Shop Sket ch

Listas arbitrárias de argumentos Finalmente, também se pode chamar a função com um número arbitrário de argumentos.

Esses argumentos serão encapsulados em uma sequência (tuplo). Antes do número variável de argumentos, zero ou mais argumentos normais podem estar presentes.

def f pr i nt f ( f i l e, f or mat , * ar gs) :

f i l e. wr i t e( f or mat % ar gs)

Funções Lambda Dado os pedidos do público, algumas características encontradas em linguagens de programação funcionais (como Lisp) foram adicionadas ao Python. Com a palavra-chave l ambda, funções curtas e anónimas podem ser criadas.

Aqui está uma função que devolve a soma de seus dois argumentos: ‘ l ambda a, b: a+b’ . Funções Lambda podem ser utilizadas em qualquer lugar que exigiria uma função tradicional. Sintacticamente, funções Lambda estão restritas a uma única expressão. Semanticamente, ela são apenas açúcar sintáctico para a definição de funções normais. Assim como definições de funções aninhadas, funções lambda não podem referenciar variáveis de um escopo mais externo, o que pode ser contornado pelo parcimonioso uso de argumentos com valores por defeito:

>>> def make_i ncr ement or ( n) :

. . . r et ur n l ambda x, i ncr =n: x+i ncr

. . .

>>> f = make_i ncr ement or ( 42)

>>> f ( 0)

42

>>> f ( 1)

43

>>>

Strings de documentação Há uma convenção sobre o conteúdo e formato de strings de documentação.

Page 40: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

40

A primeira linha deve ser sempre curta, representando um conciso sumário do propósito do objecto. Não se deve explicitamente referir ao nome ou tipo do objecto, uma vez que estas informações estão disponíveis por outros meios (excepto se o nome da função for o próprio verbo que descreve a finalidade da função). Essa linha deve começar com uma letra maiúscula e terminar com ponto.

Se existem múltiplas linhas na string de documentação, a segunda linha deve estar em branco, o sumário deve estar separado do resto da descrição. As linhas seguintes devem conter um ou mais parágrafos descrevendo as convenções da chamada ao objecto, seus efeitos colaterais, etc.

O parser do Python não toca na identação de comentários multi-linha. Portanto, ferramentas que processem strings de documentação precisam lidar com isso (se desejado). Existe uma convenção para isso. A primeira linha não nula após a linha de sumário determina a identação para o resto da string de documentação. A partir daí, os espaços em branco podem ser removidos de todas as linhas da string.

Aqui está um exemplo de uma docstring multi-linha: >>> def my_f unct i on( ) :

. . . " " " Do not hi ng, but document i t .

. . .

. . . No, r eal l y , i t doesn’ t do anyt hi ng.

. . . " " "

. . . pass

. . .

>>> pr i nt my_f unct i on. __doc__

Do not hi ng, but document i t .

No, r eal l y, i t doesn’ t do anyt hi ng.

Page 41: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Estruturas de Dados

41

EEssttrr uuttuurr aass ddee DDaaddooss

Page 42: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

42

Estruturas de Dados Este capítulo descreve alguns pontos já abordados, mas mais detalhados, e ainda adiciona outros pontos inéditos.

Listas O tipo list possui mais métodos. Aqui estão todos os métodos disponíveis para um objecto lista.

append(x) Adiciona um item ao fim da lista; equivalente a a[ l en( a) : ] = [ x ] .

extend(L) Estende a lista adicionando no fim todos os elementos da lista passada como parâmetro; equivalente a a[ l en( a) : ] = L.

insert(i, x) Insere um item em uma posição especificada. O primeiro argumento é o índice do elemento anterior ao que está para ser inserido, assim a. i nser t ( 0, x) insere no início da lista, e a. i nser t ( l en( a) , x) é equivalente a a. append( x) .

remove(x) Remove o primeiro item da lista cujo valor é x . Caso o valor x não é gerado um erro.

pop([i]) Remove o item na posição dada e o retorna o seu valor. Se nenhum item for especificado, a. pop( ) remove e retorna o último item na lista.

index(x) Retorna o índice do primeiro item cujo valor é igual ao argumento fornecido em x , se este valor não existir gera um erro.

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

sort() Ordena os itens da lista sem gerar uma nova lista.

reverse() Inverte a ordem dos elementos na lista sem gerar uma nova lista.

Um exemplo que utiliza a maioria dos métodos: >>> a = [ 66. 6, 333, 333, 1, 1234. 5]

>>> pr i nt a. count ( 333) , a. count ( 66. 6) , a. count ( ’ x ’ )

2 1 0

>>> a. i nser t ( 2, - 1)

>>> a. append( 333)

>>> a

[ 66. 6, 333, - 1, 333, 1, 1234. 5, 333]

>>> a. i ndex( 333)

1

>>> a. r emove( 333)

>>> a

[ 66. 6, - 1, 333, 1, 1234. 5, 333]

>>> a. r ever se( )

Page 43: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Estruturas de Dados

43

>>> a

[ 333, 1234. 5, 1, 333, - 1, 66. 6]

>>> a. sor t ( )

>>> a

[ - 1, 1, 66. 6, 333, 333, 1234. 5]

Usando Listas como Pilhas Os métodos da lista tornam muito fácil utilizar listas como pilhas, onde o item adicionado por último é o primeiro a ser recuperado (política “ú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 nenhum índice. Por exemplo:

>>> st ack = [ 3, 4, 5]

>>> st ack. append( 6)

>>> st ack. append( 7)

>>> st ack

[ 3, 4, 5, 6, 7]

>>> st ack. pop( )

7

>>> st ack

[ 3, 4, 5, 6]

>>> st ack. pop( )

6

>>> st ack. pop( )

5

>>> st ack

[ 3, 4]

Usando Listas como Filas Pode-se também utilizar uma lista como uma fila, onde o primeiro item adicionado é o primeiro a ser recuperado (política “primeiro a entrar, primeiro a sair”). Para adicionar um elemento ao fim da fila utiliza append( ) . Para recuperar um elemento do início da fila use pop( ) com 0 no índice. Por exemplo:

>>> queue = [ " Er i c" , " John" , " Mi chael " ]

>>> queue. append( " Ter r y" ) # Ter r y ar r i ves

>>> queue. append( " Gr aham" ) # Gr aham ar r i ves

>>> queue. pop( 0)

’ Er i c ’

>>> queue. pop( 0)

’ John’

>>> queue

Page 44: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

44

[ ’ Mi chael ’ , ’ Ter r y ’ , ’ Gr aham’ ]

Ferramentas para programação funcional Existem três funções internas que são muito úteis sobre listas: filter(), map(), e reduce().

‘ filter(function, sequence)’ retorna uma sequência (do mesmo tipo se possível), dos itens pertencentes a sequência para os quais function(item) é verdadeiro. Por exemplo, para calcular os números primos:

>>> def f ( x) : r et ur n x % 2 ! = 0 and x % 3 ! = 0

. . .

>>> f i l t er ( f , r ange( 2, 25) )

[ 5, 7, 11, 13, 17, 19, 23]

‘map(function, sequence)’ aplica function(item) para cada item da sequência e retorna uma lista dos valores retornados a cada aplicação. Por exemplo, para calcular números cúbicos:

>>> def cube( x) : r et ur n x* x* x

. . .

>>> map( cube, r ange( 1, 11) )

[ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

Mais de uma sequência pode ser passada; a função a ser aplicada deve possuir tantos parâmetros formais quantas sequências forem alimentadas para o ‘map’ . Se None for passado no lugar da função, então será aplicada uma função que apenas devolve os argumentos recebidos. Dessa forma, ‘map(None, list1, list2)’ é uma forma conveniente de concatenar listas em uma única. Por exemplo:

>>> seq = r ange( 8)

>>> def squar e( x) : r et ur n x* x

. . .

>>> map( None, seq, map( squar e, seq) )

[ ( 0, 0) , ( 1, 1) , ( 2, 4) , ( 3, 9) , ( 4, 16) , ( 5, 25) , ( 6, 36) , ( 7, 49) ]

‘ reduce(func, sequence)’ retorna um único valor construído a partir da sucessiva aplicação da função binária func a todos os elementos da lista fornecida, dois de cada vez. Por exemplo, para calcular a soma dos 10 primeiros números inteiros:

>>> def add( x, y) : r et ur n x+y

. . .

>>> r educe( add, r ange( 1, 11) )

55

Se apenas houver um único elemento na sequência fornecida como parâmetro, então o seu valor será retornado. Se a sequência for vazia uma excepção será levantada.

Um terceiro argumento pode ser passado para indicar o valor inicial. Neste caso, a redução de sequências vazias retornará o valor inicial. Se a sequência não for vazia, a redução iniciar-se-á a partir do valor inicial.

>>> def sum( seq) :

Page 45: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Estruturas de Dados

45

. . . def add( x, y) : r et ur n x+y

. . . r et ur n r educe( add, seq, 0)

. . .

>>> sum( r ange( 1, 11) )

55

>>> sum( [ ] )

0

Abrangência de Listas (List Comprehensions) Abrangência de listas (ou list comprehensions) permitem a criação de listas de forma concisa sem apelar para o uso de map( ) , f i l t er ( ) e/ou l ambda. A definição resultante tende a ser mais clara do que o uso das construções funcionais citadas anteriormente.

Cada abrangência de listas consiste numa expressão seguida da cláusula f or , seguida de zero ou mais cláusulas f or ou i f . O resultado será uma lista proveniente da avaliação da expressão no contexto das cláusulas f or e i f subsequentes. Se a expressão gerar um tuplo, a mesma deve ser inserida entre parênteses:

>>> f r eshf r ui t = [ ’ banana’ , ’ l oganber r y ’ , ’ passi on f r ui t ’ ]

>>> [ weapon. st r i p( ) f or weapon i n f r eshf r ui t ]

[ ’ banana’ , ’ l oganber r y ’ , ’ passi on f r ui t ’ ]

>>> vec = [ 2, 4, 6]

>>> [ 3* x f or x i n vec]

[ 6, 12, 18]

>>> [ 3* x f or x i n vec i f x > 3]

[ 12, 18]

>>> [ 3* x f or x i n vec i f x < 2]

[ ]

>>> [ { x: x* * 2} f or x i n vec]

[ { 2: 4} , { 4: 16} , { 6: 36} ]

>>> [ [ x , x* * 2] f or x i n vec]

[ [ 2, 4] , [ 4, 16] , [ 6, 36] ]

>>> [ x, x* * 2 f or x i n vec] # er r o - par ent eses r equer i do par a t upl os

Fi l e " <st di n>" , l i ne 1

[ x, x* * 2 f or x i n vec]

ˆ

Synt axEr r or : i nval i d synt ax

>>> [ ( x, x* * 2) f or x i n vec]

[ ( 2, 4) , ( 4, 16) , ( 6, 36) ]

>>> vec1 = [ 2, 4, 6]

>>> vec2 = [ 4, 3, - 9]

Page 46: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

46

>>> [ x* y f or x i n vec1 f or y i n vec2]

[ 8, 6, - 18, 16, 12, - 36, 24, 18, - 54]

>>> [ x+y f or x i n vec1 f or y i n vec2]

[ 6, 5, - 7, 8, 7, - 5, 10, 9, - 3]

O comando del Existe uma maneira de remover um item de uma lista a partir de seu índice, ao invés do seu valor: o comando del . Ele também pode ser utilizado para remover fatias (slices) da lista. Por exemplo:

>>> a

[ - 1, 1, 66. 6, 333, 333, 1234. 5]

>>> del a[ 0]

>>> a

[ 1, 66. 6, 333, 333, 1234. 5]

>>> del a[ 2: 4]

>>> a

[ 1, 66. 6, 1234. 5]

o del também pode ser utilizado para apagar variáveis: >>> del a

Referenciar a variável e remove-la posteriormente constitui um erro (pelo menos até que seja feita uma nova atribuição para a variável).

Tuplos e Sequências Como podemos observar, listas e strings possuem muitas propriedades em comum como indexação e operações de slicing. Listas e strings, são dois dos exemplos possíveis de sequências.

Como o Python é uma linguagem em evolução, outros tipos de sequências podem ser adicionados. Existe ainda um outro tipo de sequência já presente na linguagem: o tuplo (tuple).

Um tuplo consiste em uma sequência imutável de valores separados por vírgulas. >>> t = 12345, 54321, ’ hel l o! ’

>>> t [ 0]

12345

>>> t

( 12345, 54321, ’ hel l o! ’ )

>>> # Tupl os podem ser ani nhadas:

. . . u = t , ( 1, 2, 3, 4, 5)

>>> u

( ( 12345, 54321, ’ hel l o! ’ ) , ( 1, 2, 3, 4, 5) )

Page 47: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Estruturas de Dados

47

Os tuplos são sempre envolvidas por parênteses. Na criação, os tuplos podem ser envolvidos ou não por parênteses, desde que o contexto não exija os parênteses (como no caso da tuplo pertencer a uma expressão maior).

Tuplos podem ter os mais diversos usos: pares ordenados, registros de empregados em uma base de dados, etc.

Tuplos, assim como strings, são imutáveis. Não é possível atribuir valores a itens individuais de um tupl (pode-se simular o mesmo efeito através de operações de corte e concatenação). Também é possível criar tuplos contendo objectos mutáveis, como listas.

Um problema especial é a criação de tuplos contendo 0 ou 1 itens: a sintaxe tem certos truques para acomodar estes casos. Tuplos vazios são construídos por um par de parênteses vazios. E um tuplo unitário é construído por um único valor e uma vírgula entre parênteses (sem a vírgula o tuplo não será gerado!):

>>> empt y = ( )

>>> s i ngl et on = ’ hel l o’ , # <- - obser ve a ví r gul a ext r a

>>> l en( empt y)

0

>>> l en( s i ngl et on)

1

>>> s i ngl et on

( ’ hel l o’ , )

O comando t = 12345, 54321, ’ hel l o! ’ é um exemplo de empacotamento em tuplos (tuple packing): os valores 12345, 54321 e ’ hel l o! ’ são empacotados juntos num tuplo. A operação inversa também é possível:

>>> x, y, z = t

Isto é chamado de desempacotamento de sequência (sequence unpacking), e requer que a lista de variáveis do lado esquerdo corresponda ao comprimento da sequência à direita. Sendo assim, a atribuição múltipla é um caso de empacotamento e desempacotamento de tuplos.

Existe ainda uma certa assimetria aqui: empacotamento de múltiplos valores cria sempre tuplos, mas o desempacotamento funciona para qualquer sequência.

Dicionários Outra estrutura de dados interna de Python, e muito útil, é dicionário. Dicionários são também chamados de “memória associativa” , ou “vector associativo” . Diferentemente de sequências que são indexadas por inteiros, os dicionários são indexados por chaves (keys), que podem ser de qualquer tipo imutável (como strings e inteiros). Tuplos também podem ser chaves se contiverem apenas strings, inteiros ou outros tuplos. Se o tuplo contiver, directa ou indirectamente, qualquer valor mutável não poderá ser chave. Listas não podem ser usadas como chaves porque são mutáveis.

O melhor modelo mental de um dicionário á um conjunto não ordenado de pares chave-valor, onde as chaves são únicas em uma dada instância do dicionário.

Page 48: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

48

Dicionários são delimitados por : { } . Uma lista de pares chave:valor separada por vírgulas dentro desse delimitadores define a constituição inicial do dicionário. Dessa forma também será impresso o conteúdo de um dicionário numa secção de depuração.

As principais operações num dicionário são armazenar e recuperar valores a partir de chaves. Também ´e possível remover um par chave:valor com o comando del . Se você armazenar um valor utilizando uma chave já presente, o antigo valor será substituído pelo novo. Se tentar recuperar um valor dada uma chave inexistente será gerado um erro.

O método keys( ) do dicionário retorna a lista de todas as chaves presentes no dicionário, em ordem aleatória (se desejar ordená-las basta aplicar o método sor t ( ) na lista devolvida). Para verificar a existência de uma chave, utilize o método has key( ) do dicionário.

A seguir, um exemplo de uso do dicionário:

>>> t el = { ’ j ack’ : 4098, ’ sape’ : 4139}

>>> t el [ ’ gui do’ ] = 4127

>>> t el

{ ’ sape’ : 4139, ’ gui do’ : 4127, ’ j ack’ : 4098}

>>> t el [ ’ j ack’ ]

4098

>>> del t el [ ’ sape’ ]

>>> t el [ ’ i r v ’ ] = 4127

>>> t el

{ ’ gui do’ : 4127, ’ i r v ’ : 4127, ’ j ack’ : 4098}

>>> t el . keys( )

[ ’ gui do’ , ’ i r v ’ , ’ j ack’ ]

>>> t el . has_key( ’ gui do’ )

1

Condições As condições de controle utilizadas no whi l e e i f acima podem conter outros operadores além de comparações.

Os operadores de comparação i n e not i n verificam se um valor ocorre (ou não ocorre) em uma dada sequência.

Os operadores i s e i s not comparam se dois objectos são na verdade o mesmo objecto; o que só é significativo no contexto de objectos mutáveis, como listas. Todos operadores de comparação possuem a mesma precedência, que é menor do que a prioridade dos operadores numéricos.

Comparações podem ser encadeadas: a < b == c testa se a é menor que b e ainda por cima se b é igual a c .

Comparações podem ser combinadas através de operadores boleanos and e or , e negados através de not . Estes possuem menor prioridade que os demais operadores de

Page 49: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Estruturas de Dados

49

comparação. Entre eles, not é o de maior prioridade e or o de menor. Dessa forma, a condição A and not B or C é equivalente a ( A and ( not B) ) or C. Naturalmente os parênteses podem ser usados para expressar o agrupamento desejado.

Os operadores boleanos and e or são também operadores atalhos : seus argumentos são avaliados da esquerda para a direita, e a avaliação pára quando o resultado se torna conhecido. Ex., se A e C são verdadeiros mas B é falso, então A and B and C não irá avaliar a expressão C. Em geral, o valor de retorno de um operador atalho, quando usado sobre valores genéricos e não como boleanos, é o último valor avaliado na expressão.

É possível atribuir o resultado de uma comparação ou outra expressão boleana para uma variável. Por exemplo :

>>> st r i ng1, st r i ng2, st r i ng3 = ’ ’ , ’ Tr ondhei m’ , ’ Hammer Dance’

>>> non_nul l = st r i ng1 or st r i ng2 or st r i ng3

>>> non_nul l

’ Tr ondhei m’

Observe que no Python, ao contrário do C, a atribuição não pode ocorrer dentro de uma expressão. Programadores de C podem resmungar, mas isso evita toda uma classe de problemas frequentemente encontrados nos programas C: digitar = numa expressão quando a intenção era ==.

Comparando sequências e outros tipos Objectos sequência podem ser comparados com outros objectos sequência, desde que o tipo das sequências seja o mesmo. A comparação utiliza a ordem l´exicografica : primeiramente os dois primeiros itens são comparados, e se diferirem isto irá determinar o resultado da comparação, caso contrário os próximos dois itens serão comparados, e assim por diante até que se tenha exaurido alguma das sequências. Se numa comparação de itens, os mesmos forem também sequências (aninhadas), então é disparada recursivamente outra comparação lexicográfica. Se todos os itens da sequência forem iguais, então as sequências são ditas iguais. Se uma das sequências é uma subsequência da outra, então a subsequência é dita menor (operador ¡). A comparação lexicográfica utiliza Ascii para definir a ordenação. Alguns exemplos de comparações entre sequências do mesmo tipo:

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

[ 1, 2, 3] < [ 1, 2, 4]

’ ABC’ < ’ C’ < ’ Pascal ’ < ’ Pyt hon’

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

( 1, 2) < ( 1, 2, - 1)

( 1, 2, 3) == ( 1. 0, 2. 0, 3. 0)

( 1, 2, ( ’ aa’ , ’ ab’ ) ) < ( 1, 2, ( ’ abc’ , ’ a’ ) , 4)

Observe-se que é permitido comparar objectos de diferentes tipos. O resultado é determinístico, porém, arbitrário: os tipos são ordenados pelos seus nomes. Então, uma lista é sempre menor do que uma string, uma string é sempre menor do que um tuplo, etc.

Page 50: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

50

Tipos numéricos mistos são comparados de acordo com seus valores numéricos, logo 0 é igual a 0.0, etc.

Page 51: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Módulos

51

MM óódduullooss

Page 52: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

52

Módulos Se se sair do interpretador do Python e entrar novamente, todas as definições de funções e variáveis serão perdidas.

Logo, se se desejar escrever um programa que dure é melhor preparar o código num editor de texto. Quando estiver pronto, corra-se o interpretador sobre o arquivo fonte gerado. A isto chama-se gerar um script.

Á medida que os programas crescem, pode ser desejável dividi-los em vários arquivos para facilitar a manutenção. Talvez até se queira reutilizar uma função sem copiar a sua definição a cada novo programa.

Para permitir isto, Python possui uma maneira de depositar definições num arquivo e posteriormente reutilizá-las num script ou secção interactiva do interpretador. Esse arquivo é denominado módulo. As definições de um módulo podem ser importadas por outros módulos ou no módulo principal.

Um módulo é um arquivo contendo definições e comandos Python. O nome do arquivo recebe o sufixo ‘ .py’ .

Dentro de um módulo, seu nome (uma string) está disponível na variável global __name__ . Por exemplo, crie o arquivo ‘ fibo.py’ no directório corrente com o seguinte conteúdo:

# Módul o Sequênci as de Fi bonacci

def f i b( n) : # wr i t e Fi bonacci ser i es up t o n

a, b = 0, 1

whi l e b < n:

pr i nt b,

a, b = b, a+b

def f i b2( n) : # r et ur n Fi bonacci ser i es up t o n

r esul t = [ ]

a, b = 0, 1

whi l e b < n:

r esul t . append( b)

a, b = b, a+b

r et ur n r esul t

Agora inicie o interpretador do Python e importe o módulo da seguinte forma: >>> i mpor t f i bo

Isso não incorpora as funções definidas em f i bo directamente na tabela de símbolos corrente, apenas coloca o nome do módulo lá. Através do nome do módulo pode-se aceder às funções:

>>> f i bo. f i b( 1000)

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

Page 53: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Módulos

53

>>> f i bo. f i b2( 100)

[ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

>>> f i bo. __name__

’ f i bo’

Se se pretender utilizar uma função frequentemente, é possível atribuir-lhe um nome local:

>>> f i b = f i bo. f i b

>>> f i b( 500)

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

Um módulo pode conter tantos comandos como definições. Os comandos servem ao propósito de inicializar o módulo, sendo executados apenas na primeira vez em que o mesmo é importado. Cada módulo possui a sua própria tabela de símbolos, que é usada como tabela de símbolos global por todas as funções definidas no próprio módulo. Portanto, o autor do módulo pode utilizar variáveis globais no módulo sem se preocupar com colisões de nomes acidental com as variáveis globais de usuário.

Por outro lado, se se souber o que se está a fazer, é possível o acesso às variáveis globais do módulo através da mesma notação. O que permite o acesso às funções do módulo: modname. i t emname.

Os módulos podem ser importados por outros módulos. É costume, mas não obrigatório, colocar todos os comandos de importação (i mpor t ) no início do módulo.

Existe uma variante do comando i mpor t statement que importa nomes de um dado módulo directamente para a tabela do módulo importador. Os nomes do módulo importado são adicionados à tabela de símbolos global do módulo importador. Por exemplo:

>>> f r om f i bo i mpor t f i b, f i b2

>>> f i b( 500)

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

Isso não introduz o nome do módulo importado na tabela de símbolos local, mas sim o nome da função directamente.

Existe ainda uma variante que permite importar directamente todos os nomes definidos em um dado módulo.

>>> f r om f i bo i mpor t *

>>> f i b( 500)

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

Isso importa todos os nomes excepto aqueles iniciados por um sublinhado (_).

O Caminho de busca dos módulos Quando um módulo denominado spam é importado, o interpretador busca por um arquivo chamado ‘spam.py’ no directório corrente, depois na lista de directórios especificados pela variável de ambiente PYTHONPATH. Esta última possui a mesma

Page 54: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

54

sintaxe da variável de ambiente PATH, isto é, uma lista de caminhos. Quando PYTHONPATH não existir, ou o arquivo não for achado nesta lista, a busca continua num caminho que depende da instalação. No caso do Unix esse caminho é quase sempre ‘ .:/usr/local/lib/python’ .

De facto, módulos são procurados pela lista de caminhos especificados na variável sys. pat h inicializada com os caminhos citados acima, o que permite aos programas Python manipularem o processo de busca de módulos se desejado.

Arquivos Python “ Compilados” Um factor que agiliza a carga de programas curtos que utilizam muitos módulos padrão é a existência de um arquivo com extensão ‘ .pyc’ no mesmo directório do fonte ‘ .py’ . O arquivo ‘ .pyc’ contém uma versão “byte-compilada” do fonte ‘ .py’ . A data de modificação de ‘ .py’ é armazenada dentro do ‘ .pyc’ , e verificada automaticamente antes da utilização do último. Se não conferir, o arquivo ‘ .pyc’ existente é re-compilado a partir do ‘ .py’ mais actual.

Normalmente, não é preciso fazer nada para gerar o arquivo ‘ .pyc’ . Sempre que um módulo ‘ .py’ ´e compilado com sucesso, é feita uma tentativa de se escrever sua versão compilada para o ‘ .pyc’ . Não há geração de erro se essa tentativa falhar. Se por qualquer razão o arquivo compilado não é inteiramente escrito em disco, o ‘ .pyc’ resultante será reconhecido como inválido e, portanto, ignorado. O conteúdo do ‘ .pyc’ é independente de plataforma, assim um directório de módulos do Python pode ser compartilhado por diferentes arquitecturas.

Algumas dicas úteis:

_ Quando o interpretador Python é invocado com a directiva -O, código optimizado é gerado e armazenado em arquivos ‘ .pyo’ . O optimizador corrente não faz muita coisa, ele apenas remove construções asser t e instruções SET_LI NENO. Quando o -O é utilizado, todo o bytecode é optimizado. Arquivos . pyc são ignorados e arquivos . py são compilados em bytecode optimizado.

_ Passando duas flags -O ao interpretador (-OO) irá forçar o compilador de bytecode a efectuar optimizações arriscadas que poderiam em casos raros acarretar o mal funcionamento de programas. Presentemente, apenas strings __doc__ são removidas do bytecode, proporcionando arquivos ‘ .pyo’ mais compactos. Uma vez que alguns programas podem supor a existência das docstrings, é melhor só usar isto se tiver a segurança de que não irá acarretar nenhum efeito colateral negativo.

_ Um programa não executa mais rápido quando é lido de um arquivo ‘ .pyc’ ou de um ‘ .pyo’ em comparação a quando é lido de um ‘ .py’ . A única diferença é que nos dois primeiros casos o tempo que demora a carregar o programa é menor.

_ Quando um script é executado directamente a partir de seu nome da linha de comando, não são geradas as formas compiladas desse script em arquivos ‘ .pyo’ ou ‘ .pyc’ . Portanto, o tempo de carga de um script pode ser melhorado se transportarmos a maioria de seu código para um módulo e utilizarmos outro script apenas para correr o script inicial. É possível correr o interpretador directamente sobre arquivos compilados.

Page 55: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Módulos

55

_ Na presença das formas compiladas (‘ .pyc’ e‘ .pyo’ ) de um script, não há necessidade da presença da forma textual(‘ .py’ ).

_ O módulo compi l eal l pode criar arquivos ‘ .pyc’ (ou ‘ .pyo’ quando é usado -O) para todos os módulos num dado directório.

Módulos Padrão O Python possui um biblioteca padrão de módulos, descrita em um documento em separado, a Python Library Reference. Alguns módulos estão embutidos no interpretador; estes possibilitam acesso a operações que não são parte do núcleo da linguagem, seja por eficiência ou para permitir o acesso a chamadas de sistema. O conjunto presente destes módulos é configurável, por exemplo, o módulo amoeba só está disponível em sistemas que suportam as primitivas do Amoeba. Existe um módulo que requer especial atenção: sys , que é embutido em qualquer interpretador Python. As variáveis sys. ps1 e sys. ps2 definem as strings utilizadas como prompt primário e secundário:

>>> i mpor t sys

>>> sys. ps1

’ >>> ’

>>> sys. ps2

’ . . . ’

>>> sys. ps1 = ’ C> ’

C> pr i nt ’ Yuck! ’

Yuck!

C>

Essas variáveis só estão definidas se o interpretador está em modo interactivo.

A variável sys. pat h contém uma lista de strings que determina os caminhos de busca de módulos conhecidos pelo interpretador. Ela é inicializada para um caminho por defeito determinado pela variável de ambiente PYTHONPATH ou por um valor interno, por defeito, caso a variável não estiver definida. A lista de strings com os caminhos de busca pode ser modificada, usado para isso as operações típicas das lista:

>>> i mpor t sys

>>> sys. pat h. append( ’ / uf s/ gui do/ l i b/ pyt hon’ )

A Função dir() A função interna di r ( ) é utilizada para se descobrir que nomes são definidos por um módulo. Ela retorna uma lista ordenada de strings:

>>> i mpor t f i bo, sys

>>> di r ( f i bo)

[ ’ __name__’ , ’ f i b’ , ’ f i b2’ ]

>>> di r ( sys)

[ ’ __name__’ , ’ ar gv’ , ’ bui l t i n_modul e_names’ , ’ copyr i ght ’ , ’ exi t ’ ,

Page 56: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

56

’ maxi nt ’ , ’ modul es’ , ’ pat h’ , ’ ps1’ , ’ ps2’ , ’ set pr of i l e’ , ’ set t r ace’ ,

’ st der r ’ , ’ s t di n’ , ’ st dout ’ , ’ ver s i on’ ]

Sem nenhum argumento, di r ( ) lista os nomes correntemente definidos: >>> a = [ 1, 2, 3, 4, 5]

>>> i mpor t f i bo, sys

>>> f i b = f i bo. f i b

>>> di r ( )

[ ’ __name__’ , ’ a’ , ’ f i b’ , ’ f i bo’ , ’ sys’ ]

Observe-se que são listados os nomes dos mais diversos tipos: variáveis, módulos, funções, etc.

di r ( ) não lista nomes de funções ou variáveis internas. Esse nomes estão definidos no módulo padrão __bui l t i n__ :

>>> i mpor t __bui l t i n__

>>> di r ( __bui l t i n__)

[ ’ AccessEr r or ’ , ’ At t r i but eEr r or ’ , ’ Conf l i c t Er r or ’ , ’ EOFEr r or ’ , ’ I OEr r or ’ ,

’ I mpor t Er r or ’ , ’ I ndexEr r or ’ , ’ KeyEr r or ’ , ’ Keyboar dI nt er r upt ’ ,

’ Memor yEr r or ’ , ’ NameEr r or ’ , ’ None’ , ’ Over f l owEr r or ’ , ’ Runt i meEr r or ’ ,

’ Synt axEr r or ’ , ’ Syst emEr r or ’ , ’ Syst emExi t ’ , ’ TypeEr r or ’ , ’ Val ueEr r or ’ ,

’ Zer oDi v i si onEr r or ’ , ’ __name__’ , ’ abs’ , ’ appl y ’ , ’ chr ’ , ’ cmp’ , ’ coer ce’ ,

’ compi l e’ , ’ di r ’ , ’ di vmod’ , ’ eval ’ , ’ execf i l e’ , ’ f i l t er ’ , ’ f l oat ’ ,

’ get at t r ’ , ’ hasat t r ’ , ’ hash’ , ’ hex’ , ’ i d’ , ’ i nput ’ , ’ i nt ’ , ’ l en’ , ’ l ong’ ,

’ map’ , ’ max’ , ’ mi n’ , ’ oct ’ , ’ open’ , ’ or d’ , ’ pow’ , ’ r ange’ , ’ r aw_i nput ’ ,

’ r educe’ , ’ r el oad’ , ’ r epr ’ , ’ r ound’ , ’ set at t r ’ , ’ st r ’ , ’ t ype’ , ’ xr ange’ ]

Pacotes Pacotes são uma maneira de estruturar espaços de nomes para módulos utilizando a sintaxe de “separação por ponto” . Como exemplo, o módulo A. B designa um sub-módulo chamado ‘B’ num pacote denominado ‘A’ . O uso de pacotes permite aos autores de grupos de módulos (como NumPy ou PIL) não terem que se preocupar com a colisão entre os nomes de seus módulos e os nomes de módulos de outros autores.

Suponhamos que se desejava projectar uma colecção de módulos (um “pacote”) para o gerar uniformemente arquivos de som. Existem muitos formatos diferentes (normalmente identificados pela extensão do nome de arquivo, ex. ‘ .wav’ , ‘ .aiff’ , ‘ .au’ ), de forma que você pode precisar criar e manter uma crescente colecção de módulos de conversão entre formatos. Ainda podem existir muitas operações diferentes passíveis de aplicação sobre os arquivos de som (ex. mix, eco, equalização, efeito stereo artificial). Logo, possivelmente estaríamos a escrever uma interminável colecção de módulos para aplicar estas operações. Aqui está uma possível estrutura para o pacote (expressa em termos de um sistema hierárquico de arquivos):

Sound/ Top- l evel package

Page 57: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Módulos

57

__i ni t __. py I ni t i al i ze t he sound package

For mat s/ Subpackage f or f i l e f or mat conver si ons

__i ni t __. py

wavr ead. py

wavwr i t e. py

ai f f r ead. py

ai f f wr i t e. py

aur ead. py

auwr i t e. py

. . .

Ef f ect s/ Subpackage f or sound ef f ect s

__i ni t __. py

echo. py

sur r ound. py

r ever se. py

. . .

Fi l t er s/ Subpackage f or f i l t er s

__i ni t __. py

equal i zer . py

vocoder . py

kar aoke. py

. . .

Os arquivos ‘__init__.py’ são necessários para que o Python trate os directórios como um conjunto de módulos. Isso foi feito para evitar directórios com nomes comuns, como ‘st r i ng’ , de inadvertidamente esconder módulos válidos que ocorram a posteriori no caminho de busca. No caso mais simples, ‘__init__.py’ pode ser um arquivo vazio. Porém, ele pode conter código de inicialização para o pacote ou gerar a variável __al l __, que será descrita depois.

Usuários do pacote podem importar módulos individuais, por exemplo: i mpor t Sound. Ef f ect s. echo

Assim se carrega um sub-módulo Sound. Ef f ect s. echo. Ele deve ser referenciado com seu nome completo, como em:

Sound. Ef f ect s. echo. echof i l t er ( i nput , out put , del ay=0. 7, at t en=4)

Uma alternativa para a importação é: f r om Sound. Ef f ect s i mpor t echo

Assim carrega-se o módulo sem necessidade de prefixação na hora do uso. Logo, pode ser utilizado como se segue:

echo. echof i l t er ( i nput , out put , del ay=0. 7, at t en=4)

Também é possível importar directamente uma única variável ou função, como em: f r om Sound. Ef f ect s. echo i mpor t echof i l t er

Page 58: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

58

Novamente, o sub-módulo echo é carregado, mas a função echof i l t er ( ) está acessível directamente sem prefixação:

echof i l t er ( i nput , out put , del ay=0. 7, at t en=4)

Note-se que ao utilizar f r om package i mpor t item, o item pode ser um sub-pacote, sub-módulo, classe, função ou variável. O comando i mpor t primeiro testa se o item está definido no pacote, senão assume que é um módulo e tenta carregá-lo. Se falhar em encontrar o módulo uma excepção I mpor t Er r or é levantada.

Em oposição, na construção i mpor t item.subitem.subsubitem, cada item, com excepção do último, deve ser um pacote. O último pode ser também um pacote ou módulo, mas nunca uma entidade contida num módulo.

Importando * de um pacote O que acontece quando um usuário escreve f r om Sound. Ef f ect s i mpor t * ?

Idealmente, poder-se-ia esperar que todos os sub-módulos presentes no pacote fossem importados. Infelizmente, essa operação não funciona muito bem nas plataformas Mac ou Windows, onde não existe distinção entre maiúsculas ou minúsculas nos sistema de arquivos. Nestas plataformas não há como saber como importar o arquivo ‘ECHO.PY’ , deveria ser com o nome echo, Echo ou ECHO (por exemplo, o Windows 95 tem o irritante hábito de colocar a primeira letra em maiúsculas). A restrição de nomes de arquivo em DOS com o formato 8+3 adiciona um outro problema na hora de se utilizar arquivos com nomes longos.

A única solução é o autor do pacote fornecer um índice explícito do pacote. O comando de importação utiliza a seguinte convenção: se o arquivo ‘__init__.py’ do pacote define-se a lista chamada __al l __ , então esta lista indica os nomes dos módulos a serem importados quando o comando f r om package i mpor t * é encontrado.

Fica a cargo do autor do pacote manter esta lista actualizada, inclusive fica ao seu critério excluir inteiramente o suporte a importação directa de todo o pacote através do f r om package i mpor t * . Por exemplo, o arquivo ‘Sounds/Effects/__init__.py’ poderia conter apenas:

__al l __ = [ " echo" , " sur r ound" , " r ever se" ]

Isso significaria que f r om Sound. Ef f ect s i mpor t * iria importar apenas os três sub-módulos especificados no pacote Sound.

Se __al l __ não estiver definido, o comando f r om Sound. Ef f ect s i mpor t * não irá importar todos os sub-módulos do pacote Sound. Ef f ect s no espaço de nomes correntes. Há apenas garantia que o pacote Sound. Ef f ect s foi importado (possivelmente executou o seu código de inicialização ‘__init__.py’ ) juntamente com os nomes definidos no pacote. Isso inclui todos os nomes definidos no ‘__init__.py’ bem como em qualquer sub-módulo importado a partir deste. Por exemplo:

i mpor t Sound. Ef f ect s. echo

i mpor t Sound. Ef f ect s. sur r ound

f r om Sound. Ef f ect s i mpor t *

Page 59: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Módulos

59

Neste exemplo, os módulos echo e surround são importados no espaço de nomes correntes, pois estão definidos no pacote Sound. Ef f ect s . O que também funciona quando __al l __ estiver definida.

Em geral, a prática de importar tudo de um dado módulo é desaconselhada, principalmente por prejudicar a legibilidade do código. Contudo, é recomendada em sessões interactivas para evitar excesso de digitação.

Não existe nade de errado em utilizar f r om Package i mpor t speci f i c_submodul e! De facto, essa é a notação recomendada a menos que o módulo para efectuar a importação precise utilizar sub-módulos homónimos em diferentes pacotes.

Referências num mesmo pacote Os sub-módulos frequentemente precisam referenciar-se uns aos outros. Por exemplo, o módulo sur r ound talvez precise utilizar o módulo echo. De fato, tais referências são tão comuns que o comando i mpor t primeiro procura módulos dentro do pacote antes de utilizar o caminho de busca padrão. Portanto, o módulo sur r ound pode usar simplesmente i mpor t echo ou f r om echo i mpor t echof i l t er . Se o módulo importado não for encontrado no pacote corrente (o pacote do qual o módulo corrente é sub-módulo), então o comando i mpor t procura por um módulo de mesmo nome no escopo global.

Quando pacotes são estruturados em sub-pacotes (como em Sound), não existe atalho para referenciar sub-módulos de pacotes irmãos - o nome completo do pacote deve ser utilizado. Por exemplo, se o módulo Sound. Fi l t er s. vocoder precisa utilizar o módulo echo no pacote Sound. Ef f ect s , é preciso importá-lo como: f r om Sound. Ef f ect s i mpor t echo.

Page 60: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

60

Page 61: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Entrada e Saída

61

EEnnttrr aaddaa ee SSaaííddaa

Page 62: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

62

Entrada e Saída Existem diversas maneiras de se apresentar a saída (output) de um programa. Os dados podem ser impressos em forma imediatamente legível, ou escritos num arquivo para uso futuro. Este capítulo vai discutir algumas das possibilidades.

Formatação de Saída Até agora nós encontramos duas maneiras de escrever valores: através de expressões e pelo comando pr i nt (uma terceira maneira é utilizar o método wr i t e( ) dos objectos de arquivo; a saída padrão pode ser referenciada como sys. st dout ).

Frequentemente deseja-se um controle maior sobre a formatação de saída do que simplesmente imprimindo valores separados por espaços. Existem duas formas. A primeira manipular a string através de recortes (slicing) e concatenação. O módulo padrão st r i ng contém algumas rotinas úteis a esta finalidade. A segunda maneira é utilizar o operador %.

O operador % interpreta o argumento à esquerda como uma string de formatação de um spr i nt f ( ) aplicada ao argumento à direita do operador. O resultado é uma string formatada.

Permanece a questão: como converter valores para strings? Por sorte, o Python possui uma maneira de converter qualquer valor para uma string: basta submetê-lo à função r epr ( ) , ou simplesmente escrevê-lo entre aspas reversas (‘ ‘ ). Alguns exemplos:

>>> x = 10 * 3. 14

>>> y = 200* 200

>>> s = ’ The val ue of x i s ’ + ‘ x ‘ + ’ , and y i s ’ + ‘ y ‘ + ’ . . . ’

>>> pr i nt s

The val ue of x i s 31. 4, and y i s 40000. . .

>>> # Aspas r ever sas t ambém f unci onam em out r os t i pos al em de númer os:

. . . p = [ x, y]

>>> ps = r epr ( p)

>>> ps

’ [ 31. 400000000000002, 40000] ’

>>> # Conver t er uma st r i ng adi ci ona bar r as i nver t i das e aspas

. . . hel l o = ’ hel l o, wor l d\ n’

>>> hel l os = ‘ hel l o‘

>>> pr i nt hel l os

’ hel l o, wor l d\ n’

>>> # O ar gument o de aspas r ever sas pode ser um t upl o

. . . ‘ x, y , ( ’ spam’ , ’ eggs’ ) ‘

" ( 31. 400000000000002, 40000, ( ’ spam’ , ’ eggs’ ) ) "

Page 63: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Entrada e Saída

63

A seguir, duas maneiras de se escrever uma tabela de quadrados e cubos: >>> i mpor t st r i ng

>>> f or x i n r ange( 1, 11) :

. . . pr i nt st r i ng. r j ust ( ‘ x ‘ , 2) , s t r i ng. r j ust ( ‘ x* x ‘ , 3) ,

. . . # Obser ve a v´ ýr gul a f i nal na l i nha ant er i or

. . . pr i nt st r i ng. r j ust ( ‘ x* x* x ‘ , 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

>>> f or x i n r ange( 1, 11) :

. . . pr i nt ’ %2d %3d %4d’ % ( 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

De notar que os espaços adicionados entre as colunas devem-se a forma de funcionamento do comando pr i nt : ele adiciona sempre espaços entre seus argumentos. Este exemplo demonstra a função st r i ng. r j ust ( ) , que justifica uma string à direita gerando espaços adicionais à esquerda. Existem funções análogas st r i ng. l j ust ( ) e st r i ng. cent er ( ) . Essas funções apenas retornam a string formatada. Se a entrada extrapolar o comprimento exigido a string original é devolvida sem ser modificada. A razão para isso é não apresentar um valor potencialmente corrompido por truncamento (se for desejado truncar o valor pode-se utilizar operações de recorte como em ‘st r i ng. l j ust ( x, n) [ 0: n] ’ ).

Page 64: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

64

Existe ainda a função st r i ng. zf i l l ( ) que preenche uma string numérica com zeros à esquerda. Ela entende sinais positivos e negativos.

>>> i mpor t st r i ng

>>> st r i ng. zf i l l ( ’ 12’ , 5)

’ 00012’

>>> st r i ng. zf i l l ( ’ - 3. 14’ , 7)

’ - 003. 14’

>>> st r i ng. zf i l l ( ’ 3. 14159265359’ , 5)

’ 3. 14159265359’

Um exemplo de uso do operador %: >>> i mpor t mat h

>>> pr i nt ’ The val ue of PI i s appr oxi mat el y %5. 3f . ’ % mat h. pi

The val ue of PI i s appr oxi mat el y 3. 142.

Se houver mais do que um formato, então o argumento à direita deve ser um tuplo com os valores de formatação.

Exemplo: >>> t abl e = { ’ Sj oer d’ : 4127, ’ Jack’ : 4098, ’ Dcab’ : 7678}

>>> f or name, phone i n t abl e. i t ems( ) :

. . . pr i nt ’ %- 10s ==> %10d’ % ( name, phone)

. . .

Jack ==> 4098

Dcab ==> 7678

Sj oer d ==> 4127

A maioria dos formatos funciona da mesma maneira que em C, e exigem que se passe o tipo apropriado. Entretanto, em caso de erro ocorre uma excepção e não uma falha do sistema operativo.

O formato %s é mais relaxado: se o argumento correspondente não for um objecto string, então ele é convertido para string pela função interna st r ( ) . Existe um suporte para o modificador * determinar o comprimento ou precisão num argumento inteiro em separado. Os formatadores (em C) %n e %p também são suportados.

Se se possuir uma string de formatação muito longa, seria bom referenciar as variáveis de formatação por nome, ao invés de por posição. Isso pode ser obtido passando um dicionário como argumento à direita e prefixando campos na string de formatação com %( name) f or mat .

>>> t abl e = { ’ Sj oer d’ : 4127, ’ Jack’ : 4098, ’ Dcab’ : 8637678}

>>> pr i nt ’ Jack: %( Jack) d; Sj oer d: %( Sj oer d) d; Dcab: %( Dcab) d’ % t abl e

Jack: 4098; Sj oer d: 4127; Dcab: 8637678

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

Page 65: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Entrada e Saída

65

Leitura e escrita de arquivos A funcão open( ) retorna um objecto de arquivo, e é frequentemente usada com dois argumentos: ‘open( filename, mode) ’ .

>>> f =open( ’ / t mp/ wor kf i l e’ , ’ w’ )

>>> pr i nt f

<open f i l e ’ / t mp/ wor kf i l e’ , mode ’ w’ at 80a0960>

O primeiro argumento é uma string contendo o nome do arquivo. O segundo argumento é outra string contendo alguns caracteres que descrevem o modo como o arquivo será usado. O parâmetro mode pode assumir valor ’ r ’ quando o arquivo será só de leitura, ’ w’ quando for só de escrita (se o arquivo já existir seu conteúdo prévio será apagado), e ’ a’ para abrir o arquivo para adição; qualquer escrita será adicionada ao final do arquivo. A opção ’ r +’ abre o arquivo tanto para leitura como para escrita. O parâmetro mode é opcional, em caso de omissão será assumido ’ r ’ .

No Windows e no Macintosh, ’ b’ adicionado à string de modo indica que o arquivo será aberto no formato binário. Sendo assim, existem os modos compostos : ’ r b’ , ’ wb’ , e ’ r +b’ . O Windows faz distinção entre arquivos texto e binários: os caracteres terminadores de linha em arquivos texto são levemente alterados em leituras e escritas. Essa mudança “por detrás do pano” é útil em arquivos texto Ascii, mas irá corromper um arquivo binário como no caso de JPEGs ou executáveis. Deve-se ser muito cuidadoso ao manipular arquivos binários (no caso do Macintosh a semântica exacta do modo texto, depende da biblioteca C subjacente que é utilizada).

Métodos dos objectos de arquivos A título de simplificação, o resto dos exemplos nesta secção irão assumir que o objecto de arquivo chamado f já foi criado.

Para se ler o conteúdo de um arquivo chame f . r ead( size) , que lê uma quantidade de dados retornando-os como uma string. O argumento numérico size é opcional. Quando size for omitido ou negativo, todo o conteúdo do arquivo será lido e retornado. Caso contrário, no máximo size bytes serão lidos e retornados. Se o fim do arquivo for atingido, f . r ead( ) irá retornar uma string vazia ().

>>> f . r ead( )

’ Esse é t odo o cont eúdo do ar qui vo. \ n’

>>> f . r ead( )

’ ’

f . r eadl i ne( ) lê uma única linha do arquivo. O caracter de retorno de linha (\ n) é deixado ao final da string, só sendo omitido na última linha do arquivo se ele já não estiver presente lá. Isso elimina a ambiguidade no valor de retorno. Se f . r eadl i ne( ) retornar uma string vazia, então o arquivo acabou. Linhas em branco são representadas por ’ \ n’ : uma string contendo unicamente o terminador de linha.

>>> f . r eadl i ne( )

’ Essa ´ e a pr i mei r a l i nha do ar qui vo. \ n’

Page 66: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

66

>>> f . r eadl i ne( )

’ Segunda l i nha do ar qui vo\ n’

>>> f . r eadl i ne( )

’ ’

f . r eadl i nes( ) retorna uma lista contendo todas as linhas do arquivo. Se for fornecido o parâmetro opcional sizehint, será lida a quantidade especificada de bytes e mais o suficiente para completar uma linha. Frequentemente, esta operação é utilizada para ler arquivos muito grandes sem ter que ler todo o arquivo para a memória de uma só vez. Apenas linhas completas serão retornadas.

>>> f . r eadl i nes( )

[ ’ Essa ´ e a pr i mei r a l i nha do ar qui vo. \ n’ , ’ Segunda l i nha do ar qui vo\ n’ ]

f . wr i t e( string) escreve o conteúdo da string para o arquivo, retornando None. >>> f . wr i t e( ’ I sso ´ e um t est e. \ n’ )

f . t el l ( ) retorna um inteiro que indica a posição corrente de leitura ou escrita no arquivo, medida em bytes desde o início do arquivo. Para mudar a posição utiliza-se ‘ f . seek( offset, from what) ’ . A nova posição é calculada pela soma do offset a um ponto de referência, que por sua vez é definido pelo argumento from what.

O argumento from what pode assumir o valor 0 para indicar o início do arquivo, 1 para indicar a posição corrente e 2 para indicar o fim do arquivo. Este parâmetro pode ser omitido, quando é assumido o valor por defeito 0.

>>> f =open( ’ / t mp/ wor kf i l e’ , ’ r +’ )

>>> f . wr i t e( ’ 0123456789abcdef ’ )

>>> f . seek( 5) # Vai par a o qui nt o byt e

>>> f . r ead( 1)

’ 5’

>>> f . seek( - 3, 2) # Vai par a o t er cei r o byt e ant es do f i m

>>> f . r ead( 1)

’ d’

Quando se acabar de utilizar o arquivo, chame-se o f . c l ose( ) para fechar o arquivo e liberar recursos. Qualquer tentativa de acesso ao arquivo depois dele ter sido fechado implicará em falha.

>>> f . c l ose( )

>>> f . r ead( )

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1, i n ?

Val ueEr r or : I / O oper at i on on c l osed f i l e

Os objectos de arquivo podem ter métodos adicionais, tais como i sat t y( ) e t r uncat e( ) que são usados com menos frequência.

O módulo pickle

Page 67: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Entrada e Saída

67

As strings podem ser facilmente escritas e lidas de um arquivo. Números exigem um pouco mais de esforço, uma vez que o método r ead( ) só trabalha com strings. Portanto, pode ser utilizada a função st r i ng. at oi ( ) , que recebe uma string ’ 123’ e a converte para o respectivo valor inteiro. Entretanto, quando estruturas de dados mais

complexas (listas, dicionários, instâncias de classe, etc) estão envolvidas, o processo torna-se mais complicado.

Para que não seja necessário que usuários estejam constantemente a escrever e a fazer debug do código, Python oferece o módulo padrão pi ckl e. Este módulo permite que praticamente qualquer objecto Python (até mesmo código!) seja convertido para uma representação string. Este processo é denominado pickling. E unpickling é o processo contrário de reconstruir o objecto a partir de sua representação em string. Enquanto estiver representado como uma string, o objecto pode ser armazenado em arquivo, transferido pela rede, etc.

Se existir um objecto qualquer x , e um objecto arquivo f que foi aberto para escrita, a maneira mais simples de utilizar este módulo é:

pi ckl e. dump( x, f )

Para desfazer, se f for agora um objecto de arquivo pronto para leitura:

x = pi ck l e. l oad( f )

Existem outras variações desse processo úteis quando se precisa aplicar sobre muitos objectos ou o destino da representação string não é um arquivo. Utilizar o módulo pi ckl e é a forma padrão de tornar objectos Python persistentes, permitindo a reutilização dos mesmos entre diferentes programas, ou pelo mesmo programa em diferentes sessões de utilização. A representação da string dos dados é tecnicamente chamada objecto persistente, como já foi visto. Justamente porque o módulo pi ckl e é amplamente utilizado, vários autores que escrevem extensões para Python tomam o cuidado de garantir que novos tipos de dados sejam compatíveis com esse processo.

Page 68: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

68

Page 69: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Erros e Excepções

69

EErr rr ooss ee EExxcceeppççõõeess

Page 70: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

70

Erros e Excepções Até agora mensagens de erro foram apenas mencionadas. Existem pelo menos dois tipos distintos de erros: erros de sintaxe e excepções.

Erros de sintaxe Erros de sintaxe, também conhecidos como erros de parse, são provavelmente os mais frequentes entre aqueles que ainda estão aprendendo Python:

>>> whi l e 1 pr i nt ’ Hel l o wor l d’

Fi l e " <st di n>" , l i ne 1

whi l e 1 pr i nt ’ Hel l o wor l d’

ˆ

Synt axEr r or : i nval i d synt ax

O parser repete a linha inválida e apresenta uma pequena ‘sete (^)’ apontando para o ponto da linha em que o erro foi encontrado. O erro é detectado pelo token que precede a seta. No exemplo, o erro foi detectado na palavra reservada pr i nt , uma vez que faltam os dois pontos (‘ : ’ ). O nome do arquivo e número da linha são impressos para que se possa verificar melhor onde ocorreu o erro no texto do script.

Excepções Mesmo que um comando ou expressão estejam sintacticamente correctos, talvez ocorra um erro na hora de sua execução. Erros detectados durante a execução são chamados excepções e não são necessariamente fatais. A maioria das excepções não são tratadas e acabam resultando em mensagens de erro:

>>> 10 * ( 1/ 0)

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1

Zer oDi v i s i onEr r or : i nt eger di v i s i on or modul o

>>> 4 + spam* 3

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1

NameEr r or : spam

>>> ’ 2’ + 2

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1

TypeEr r or : i l l egal ar gument t ype f or bui l t - i n oper at i on

A última linha da mensagem de erro indica o que aconteceu. Excepções surgem com diferentes tipos, e o tipo é impresso como parte da mensagem . Os tipos no exemplo são: Zer oDi vi s i onEr r or , NameEr r or e TypeEr r or . A string impressa como sendo

Page 71: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Erros e Excepções

71

o tipo da excepção é o nome interno da excepção que ocorreu. Isso é verdade para todas excepções pré-definidas em Python, mas não é necessariamente verdade para excepções definidas pelo usuário.

O resto da linha é detalhe que depende do tipo da excepção ocorrida.

A parte anterior da mensagem de erro apresenta o contexto onde ocorreu a excepção. Essa informação é denominada stack backtrace. Em geral, contém uma lista de linhas do código fonte, sem apresentar, no entanto, valores lidos da entrada padrão.

O documento Python Library Reference lista as excepções pré-definidas e os seus significados.

Tratamento das Excepções E possível escrever programas que tratam excepções específicas. O exemplo seguinte, pede dados ao usuário até que um inteiro válido seja fornecido, ainda permitindo que o programa seja interrompido (utilizando Cont r ol - C ou seja lá o que for que o sistema operacional suporte). Note que uma interrupção gerada pelo usuário será sinalizada pela excepção Keyboar dI nt er r upt .

>>> whi l e 1:

. . . t r y :

. . . x = i nt ( r aw_i nput ( " Ent r e com um n´ umer o: " ) )

. . . br eak

. . . except Val ueEr r or :

. . . pr i nt " Opa! Esse númer o não é vál i do. Tent e de novo. . . "

. . .

A construção t r y funciona da seguinte maneira:

• Primeiramente, a cláusula try (o conjunto de comandos entre as palavras reservadas t r y e except ) é executado.

• Se não for gerada excepção, a cláusula except é ignorada e é termina a execução da construção t r y .

• Se uma excepção ocorre durante a execução da cláusula t r y , os comandos remanescentes na cláusula são ignorados. Se o tipo da excepção ocorrida tiver sido previsto junto a alguma palavra reservada except , então essa cláusula será executada. Ao fim da cláusula também termina a execução do t r y como um todo.

• Se a excepção ocorrida não foi prevista em nenhum tratador except da construção t r y em que ocorreu, então ela é entregue a uma construção t r y mais externa. Se não existir nenhum tratador previsto para tal excepção (chamada unhandled exception), a execução encerra com uma mensagem de erro.

A construção t r y pode ter mais de uma cláusula except para especificar múltiplos tratadores para diferentes excepções. No máximo um único tratador será activado. Tratadores só são sensíveis às excepções levantadas no interior da cláusula t r y , e não

Page 72: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

72

que tenham ocorrido no interior de outro tratador num mesmo t r y . Um tratador pode ser sensível a múltiplas excepções, desde que as especifique num tuplo:

. . . except ( Runt i meEr r or , TypeEr r or , NameEr r or ) :

. . . pass

A última cláusula except pode omitir o nome da excepção, servindo como uma máscara genérica. Esse recurso de ser utilizado com extrema cautela, uma vez que isso pode esconder erros do programador e do usuário. Também pode ser utilizado para imprimir uma mensagem de erro, ou re-elevar (re-raise) a excepção de forma que um “chamador” também possa tratá-la.

i mpor t st r i ng, sys

t r y:

f = open( ’ myf i l e. t x t ’ )

s = f . r eadl i ne( )

i = i nt ( st r i ng. st r i p( s) )

except I OEr r or , ( er r no, st r er r or ) :

pr i nt " I / O er r or ( %s) : %s" % ( er r no, st r er r or )

except Val ueEr r or :

pr i nt " Coul d not conver t dat a t o an i nt eger . "

except :

pr i nt " Unexpect ed er r or : " , sys. exc_i nf o( ) [ 0]

r ai se

A construção try . . . except possui uma cláusula else opcional, que quando presente, deve ser colocada depois de todas as outras cláusulas. É útil para um código que precisa ser executado se nenhuma excepção foi levantada. Por exemplo:

f or ar g i n sys. ar gv[ 1: ] :

t r y :

f = open( ar g, ’ r ’ )

except I OEr r or :

pr i nt ’ cannot open’ , ar g

el se:

pr i nt ar g, ’ has’ , l en( f . r eadl i nes( ) ) , ’ l i nes’

f . c l ose( )

Este recurso é melhor do que simplesmente adicionar o código do else ao corpo da cláusula try, pois mantém as excepções levantadas no else num escopo diferente de tratamento das excepções levantadas na cláusula try.

Quando uma excepção ocorre, ela pode estar associada a um valor chamado argumento da excepção. A presença e o tipo do argumento dependem do tipo da excepção. Para excepções possuidoras de argumento, a cláusula else pode especificar uma variável depois da lista de nomes de excepção para receber o argumento:

>>> t r y:

Page 73: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Erros e Excepções

73

. . . spam( )

. . . except NameEr r or , x :

. . . pr i nt ’ name’ , x , ’ undef i ned’

. . .

name spam undef i ned

Se uma excepção possui argumento, ele é impresso ao final do detalhe de expressões não tratadas (unhandled exceptions).

Além disso, tratadores de excepções são capazes de capturar excepções que tenham sido levantadas no interior de funções invocadas na cláusula try. Por exemplo:

>>> def t hi s_f ai l s( ) :

. . . x = 1/ 0

. . .

>>> t r y:

. . . t hi s_f ai l s( )

. . . except Zer oDi v i s i onEr r or , det ai l :

. . . pr i nt ’ Handl i ng r un- t i me er r or : ’ , det ai l

. . .

Handl i ng r un- t i me er r or : i nt eger di v i s i on or modul o

Levantando Excepções A palavra reservada r ai se permite ao programador forçar a ocorrência de um determinado tipo de excepção. Por exemplo:

>>> r ai se NameEr r or , ’ Hi Ther e’

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1

NameEr r or : Hi Ther e

O primeiro argumento do r ai se é o nome da excepção a ser levantada. O segundo argumento, opcional, é o argumento da excepção.

Excepções definidas pelo usuário Programas podem definir novos tipos de excepções, através da criação de uma nova classe. Por exemplo:

>>> cl ass MyEr r or :

. . . def __i ni t __( sel f , val ue) :

. . . sel f . val ue = val ue

. . . def __st r __( sel f ) :

. . . r et ur n ‘ sel f . val ue‘

. . .

>>> t r y:

Page 74: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

74

. . . r ai se MyEr r or ( 2* 2)

. . . except MyEr r or , e:

. . . pr i nt ’ My except i on occur r ed, val ue: ’ , e. val ue

. . .

My except i on occur r ed, val ue: 4

>>> r ai se MyEr r or , 1

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 1

__mai n__. MyEr r or : 1

Muitos módulos padrão utilizam-se disto para reportar erros que ocorrem no interior das funções que definem.

Acções de limpeza A construção t r y possui outra cláusula opcional, cuja finalidade é permitir a implementação de acções de limpeza, que devem ser sempre executadas independentemente da ocorrência de excepções. Como no exemplo:

>>> t r y:

. . . r ai se Keyboar dI nt er r upt

. . . f i nal l y :

. . . pr i nt ’ Goodbye, wor l d! ’

. . .

Goodbye, wor l d!

Tr aceback ( most r ecent cal l l ast ) :

Fi l e " <st di n>" , l i ne 2

Keyboar dI nt er r upt

A cláusula finally é sempre executada, que ocorra quer não uma excepção. Quando ocorre a excepção, é como se a excepção fosse sempre levantada após a execução do código na cláusula finally. Mesmo que haja um br eak ou r et ur n dentro do t r y , ainda assim o f i nal l y será executado.

A construção t r y pode ser seguida da cláusula f i nal l y ou de um conjunto de cláusulas except , mas nunca ambas. Essas opções são mutuamente exclusivas.

Page 75: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Classes

75

CCllaasssseess

Page 76: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

76

Classes O mecanismo de classes no Python foi adicionado à linguagem de forma a minimizar a sobrecarga sintáctica e semântica. É uma mistura de mecanismos equivalentes encontrados em C++ e Modula-3. Assim como é válido para módulos, classes em Python não impõem barreiras entre o usuário e a definição. Contudo, dependem da “cordialidade” do usuário para não quebrar a definição. Todavia, as características mais importantes de classes foram asseguradas: o mecanismo de herança permite uma base de classes múltiplas, uma classe derivada pode sobrescrever quaisquer métodos de uma classe ancestral, um método pode invocar outro método homónimo de uma classe ancestral. E mais, objectos podem armazenar uma quantidade arbitrária de dados privados.

Na terminologia de C++, todos os membros de uma classe (incluindo dados) são public, e todos as funções membro são virtual. Não existem construtores ou destrutores especiais.

Como em Modula-3, não existem atalhos para referenciar membros do objecto de dentro dos seus métodos. Um método (função de uma classe) é declarado com um primeiro argumento explícito representando o objecto (instância da classe), que é fornecido implicitamente pela invocação.

Como em Smalltalk (e em Java), classes são objectos. Mas no Python, todos os tipos de dados são objectos, o que fornece uma semântica para importação e renomeamento (rename). Ainda como em C++ ou Modula-3, tipos pré definidos não podem ser utilizados como classes base para extensões de usuário por herança. Como em C++, mas diferentemente de Modula-3, a maioria dos operadores (aritméticos, indexação, etc) podem ser redefinidos para instâncias da classe.

Uma palavra sobre terminologia Na falta de uma universalmente aceite terminologia de classes, iremos ocasionalmente fazer uso de termos comuns a Smalltalk ou C++.

Convém também alertar para uma armadilha terminológica para pessoas familiarizados programação orientada a objectos: a palavra “objecto” no Python não implica necessariamente numa instância de classe. Como em C++ e Modula-3 é diferentemente de Smalltalk, nem todos os tipos em Python são classes: tipos básicos como inteiros, listas e arquivos não são. Contudo, todos os tipos no Python compartilham uma semântica comum que é melhor descrita pela palavra objecto.

Os objectos têm individualidade, e podem estar vinculados a múltiplos nomes (em diferentes escopos). Essa facilidade é chamada aliasing em outras linguagens. À primeira vista não é muito apreciada, e pode ser seguramente ignorada ao lidar com tipos imutáveis (números, strings, tuplos). Entretanto, aliasing tem um efeito intencional sobre a semântica do código no Python envolvendo objectos mutáveis como listas, dicionários, e a maioria das entidades externas a um programa como arquivos, janelas, etc. Alias (N.d.T: sinónimos) funcionam de certa forma como ponteiros, em benefício do programador. Por exemplo, passagem de objectos como parâmetro é barato, pois só o

Page 77: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Classes

77

ponteiro é passado na implementação. E se uma função modificar um objecto passado como argumento, essa mudança vai ser visível do local de onde foi chamada a função – o que torna obsoleta a necessidade de um duplo mecanismo de passagem de parâmetros como em Pascal.

Escopos e espaços de nomes no Python Antes de introduzir classes, é preciso falar das regras de escopo em Python. Definições de classe empregam alguns truques com espaços de nomes. Portanto, é preciso entender bem os escopos e os espaços de nomes antes.

Esse conhecimento é muito útil para o programador avançado em Python.

Um espaço de nomes é um mapeamento entre nomes e objectos. Presentemente, são implementados como dicionários, isso não é perceptível (a não ser pelo desempenho) e pode mudar no futuro. Exemplos de espaços de nomes são: o conjunto de nomes pré-definidos (funções como abs( ) e excepções), nomes globais em módulos e nomes locais numa função. De uma certa forma, os atributos de um objecto também formam um espaço de nomes. O que há de importante para saber é que não existe nenhuma relação entre nomes em espaços distintos.

Por exemplo, dois módulos podem definir uma função de nome “maximize” sem confusão – usuários dos módulos devem prefixar a função com o nome do módulo para evitar colisões.

A propósito, é utilizada a palavra atributo para qualquer nome depois de um ponto. Na expressão z. r eal , por exemplo, r eal é um atributo do objecto z . Estritamente falando, referências para nomes em módulos são atributos: na expressão modname. f uncname, modname é um objecto módulo e f uncname é seu atributo. Neste caso, existe um mapeamento directo entre os atributos de um módulo e os nomes globais definidos no módulo: eles compartilham o mesmo espaço de nomes.

Atributos podem ser somente de leitura ou não. Atributos de módulo são passíveis de atribuição, pode-se escrever ‘modname. t he_answer = 42’ , e remoção pelo comando del (‘del modname. t he_answer ’ ).

Espaços de nomes são criados em momentos diferentes e possuem diferentes longevidade. O espaço de nomes que contém os nomes pré-definidos é criado quando o interpretador se inicializa e nunca é removido. O espaço de nomes global é criado quando uma definição de um módulo é lida, e normalmente duram até à saída do interpretador.

Os comandos executados pela invocação do interpertador, ou pela leitura de um script, ou interactivamente são parte do módulo chamado __mai n__ , e portanto possuem o seu próprio espaço de nomes (os nomes pré-definidos possuem o seu próprio espaço de nomes no módulo chamado __bui l t i n__).

O espaço de nomes local para uma função é criado quando a função é chamada, e é removido quando a função retorna ou levanta uma excepção que não é tratada na própria função. Naturalmente, chamadas recursivas de uma função possuem os seus próprios espaços de nomes.

Page 78: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

78

Um escopo é uma região textual de um programa Python onde um espaço de nomes é directamente acessível. Onde “directamente acessível” significa que uma referência sem qualificador especial permite o acesso ao nome. Ainda que os escopos sejam determinados estaticamente, eles são usados dinamicamente. A qualquer momento durante a execução, existem exactamente três escopos em uso (três escopos directamente acessíveis): o escopo interno (que é o procurado primeiro) contendo nomes locais, o escopo intermediário (com os nomes globais do módulo) e o escopo externo (procurado em último) contendo os nomes pré-definidos.

Normalmente, o escopo local referencia os nomes locais da função corrente. Fora de funções, o escopo local referencia os nomes do escopo global (espaço de nomes do módulo). Definições de classes adicionam um espaço de nomes ao escopo local.

É importante perceber que escopos são determinados textualmente. O escopo global de uma função definida num módulo é o espaço de nomes deste módulo, sem importar de onde ou de que “alias” a função é invocada. Por outro lado, a efectiva busca de nomes é dinâmica, ocorrendo durante a execução. A evolução da linguagem está caminhando para uma resolução estática de nomes, em tempo de compilação, que não dependa da resolução dinâmica de nomes. (de facto, variáveis locais já são resolvidas estaticamente.)

Um detalhe especial é que atribuições são sempre vinculadas ao escopo interno. As atribuições não copiam dados, simplesmente vinculam objectos a nomes. O mesmo é verdade para as remoções. O comando ‘del x ’ remove o vínculo de x do espaço de nomes referenciado pelo escopo local. De facto, todas as operações que introduzem novos nomes usam o escopo local. Em particular, comandos i mpor t e definições de função vinculam o módulo ou a função ao escopo local (a palavra reservada gl obal pode ser usada para indicar que certas variáveis residem no escopo global ao invés do local).

Sintaxe da definição de Classes A forma mais simples de definir uma classe é:

cl ass NomeDaCl asse:

<comando- 1>

.

.

.

<comando- N>

Definições de classes, como definições de funções (comandos def ) devem ser executados antes que tenham qualquer efeito. Pode-se colocar uma definição de uma classe após um teste condicional i f ou dentro de uma função.

Na prática, os comandos dentro de uma classe serão definições de funções, mas existem outros comandos que são permitidos. As definições de funções dentro de uma classe possuem um lista peculiar de argumentos determinada pela convenção de chamada a métodos.

Page 79: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Classes

79

Quando se fornece uma definição de uma classe, um novo espaço de nomes é criado. Todas as atribuições de variáveis são vinculadas a este escopo local. Em particular, definições de funções também são armazenadas neste escopo.

Quando termina o processamento de uma definição de uma classe (normalmente, sem erros), um objecto da classe é criado. Este objecto encapsula o conteúdo do espaço de nomes criado pela definição da classe. O escopo local activo antes da definição da classe é restaurado, e o objecto classe é vinculado a este escopo com o nome dado a classe.

Objectos de Classes Objectos de Classes suportam dois tipos de operações: referências a atributos e instanciação.

Referências a atributos da classe utilizam a sintaxe padrão utilizada para quaisquer referências a atributos no Python: obj . name. Os atributos válidos são todos os nomes presentes no espaço de nomes da classe quando o objecto classe foi criado. Portanto, se a definição da classe era:

cl ass MyCl ass:

" Um exempl o si mpl es de cl asse"

i = 12345

def f ( x) :

r et ur n ’ hel l o wor l d’

então MyCl ass. i e MyCl ass. f são referências a atributos válidos, retornando um inteiro e um objecto método, respectivamente. Atributos de classe podem receber atribuições, logo pode-se mudar o valor de MyCl ass. i por atribuição. __doc__ é também um atributo válido, que retorna a docstring pertencente a classe: " Um exempl o

si mpl es de cl asse" . Instanciação da Classe também utiliza uma notação de função. Apenas tem que se fingir que o objecto classe não possui parâmetros e retorna uma nova instância da classe. Por exemplo:

x = MyCl ass( )

cria uma nova instância da classe e atribui o objecto resultante a variável local x .

A operação de instanciação (“calling” um objecto de classe) cria um objecto vazio. Muitas classes preferem criar um novo objecto num estado inicial pré determinado. Para tanto, existe um método especial que pode ser definido pela classe, __i ni t __( ) , veja:

def __i ni t __( sel f ) :

sel f . dat a = [ ]

Quando uma classe define um método __i ni t __( ) , o processo de instanciação automaticamente invoca __i ni t __( ) sobre a recém criada instância da classe. Neste exemplo, uma nova instância já inicializada pode ser obtida por:

x = MyCl ass( )

Page 80: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

80

Naturalmente, o método __i ni t __( ) pode ter argumentos para aumentar sua flexibilidade. Neste caso, os argumentos passados para a instanciação da classe serão delegados para o método __i ni t __( ) . Como ilustrado em:

>>> cl ass Compl ex:

. . . def __i ni t __( sel f , r eal par t , i magpar t ) :

. . . sel f . r = r eal par t

. . . sel f . i = i magpar t

. . .

>>> x = Compl ex( 3. 0, - 4. 5)

>>> x. r , x. i

( 3. 0, - 4. 5)

Instâncias Agora, o que podemos fazer com as instâncias ? As únicas operações reconhecidas pelas instâncias são referências a atributos. Existem dois tipos de nomes de atributos válidos.

O primeiro chama-se de atributos-de-dados, que correspondem a “variáveis da instância” em Smalltalk, e a “membros” em C++. Atributos de dados não precisam ser declarados. Assim como variáveis locais, eles passam a existir na primeira vez em que é feita uma atribuição. Por exemplo, se x é uma instância de MyCl ass criada acima, o próximo bocado de código irá imprimir o valor 16, sem deixar rastro (por causa do del ):

x. count er = 1

whi l e x. count er < 10:

x. count er = x. count er * 2

pr i nt x. count er

del x. count er

O segundo tipo de referência aos atributos das instâncias são métodos. Um método é uma função que “pertence a” uma instância (em Python, o termo método não é aplicado exclusivamente às instâncias de classes: outros tipos de objectos também podem ter métodos; por exemplo, objectos listas possuem os métodos: append, insert, remove, sort, etc). Nomes de métodos válidos de uma instância dependem de sua classe. Por definição, todos atributos de uma classe que são funções equivalem a um método presente nas instâncias. No nosso exemplo, x. f é uma referência de método válido já que MyCl ass. f é uma função, enquanto x. i não é, já que MyCl ass. i não é uma função.

Entretanto, x. f não é o mesmo que MyCl ass. f — o primeiro é um método de um objecto, o segundo é um objecto função.

Métodos dos Objectos Normalmente, um método é chamado imediatamente, isto é:

x. f ( )

Page 81: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Classes

81

No nosso exemplo o resultado será a string ’ hel l o wor l d’ . No entanto, não é obrigatório chamar o método imediatamente: como x. f é também um objecto (tipo método), ele pode ser armazenado e invocado a posteriori. Por exemplo:

xf = x. f

whi l e 1:

pr i nt xf ( )

vai imprimir ‘hel l o wor l d’ infinitamente.

O que ocorre precisamente quando um método é chamado ? Note-se que x. f ( ) foi chamado sem nenhum parâmetro, porém a definição da função f especificava um argumento. O que aconteceu com o argumento ? Certamente Python levantaria uma excepção se o argumento estivesse faltando... A resposta é obvia: o que há de especial nos métodos é que o objecto (a qual o método pertence) é passado como o primeiro argumento da função. No nosso exemplo, a chamada x. f ( ) é exactamente equivalente a MyCl ass. f ( x) . Em geral, chamar um método com uma lista de n argumentos é equivalente a chamar a função na classe correspondente passando a instância como o primeiro argumento antes dos demais argumentos.

Quando um atributo de instância é referenciado e não é um atributo de dados, a sua classe é procurada. Se o nome indica um atributo de classe válido que seja um objecto função, um objecto método é criado pela composição da instância alvo e do objecto função. Quando o método é chamado com uma lista de argumentos, ele é desempacotado, uma nova lista de argumentos é criada a partir da instância original e da lista original de argumentos do método. Finalmente, a função é chamada com a nova lista de argumentos.

Observações aleatórias Atributos de dados sobrescrevem atributos métodos homónimos. Para evitar conflitos de nome acidentais, que podem gerar bugs de difícil rastreio em programas extensos, é sábio utilizar algum tipo de convenção que minimize conflitos, como colocar nomes de métodos com inicial maiúscula, prefixar atributos de dados com uma string única (quem sabe “ ” ), ou simplesmente utilizar substantivos para atributos e verbos para métodos.

Os atributos de dados podem ser referenciados por métodos da própria instância, bem como por qualquer outro usuário do objecto. Em outras palavras, classes não servem para implementar tipos puramente abstractos de dados.

De fato, nada no Python torna possível assegurar o encapsulamento de dados. Tudo é convenção. Por outro lado, a implementação do Python, escrita em C, pode esconder completamente detalhes de um objecto ou regular seu acesso se necessário. Isto pode ser utilizado por extensões ao Python escritas em C.

Os clientes devem utilizar atributos de dados com cuidado, pois podem baralhar invariantes mantidos pelos métodos ao esbarrar nos seus atributos. Portanto, os clientes podem adicionar à vontade atributos de dados para uma instância sem afectar a validade dos métodos, desde que seja evitado o conflito de nomes. Novamente, uma convenção de nomenclatura poupa muita dor de cabeça.

Page 82: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

82

Não existe um atalho para referenciar atributos de dados (ou métodos) de dentro de um método. Isso na verdade aumenta a legibilidade dos métodos: não há como confundir uma variável local com uma instância global ao dar uma olhadela num método desconhecido.

Por convenção, o primeiro argumento de qualquer método é frequentemente chamado sel f . Isso não é nada mais do que uma convenção, sel f não possui nenhum significado especial em Python. Observe que ao seguir a convenção, o código torna-se legível por uma grande comunidade de desenvolvedores de Python e potencialmente poder-se-á vir a beneficiar de ferramentas feitas por outra pessoa que se baseie na convenção.

Qualquer função que seja também atributo de classe define um método nas instâncias desta classe. Não é necessário que a definição da função esteja textualmente embutida na definição da classe. Atribuir um objecto função a uma variável local da classe é válido. Por exemplo:

# Função def i ni da f or a da c l asse

def f 1( sel f , x , y) :

r et ur n mi n( x, x+y)

c l ass C:

f = f 1

def g( sel f ) :

r et ur n ’ hel l o wor l d’

h = g

Agora f , g e h são todos atributos da classe C que referenciam funções, e consequentemente são todos métodos de instâncias da classe C, onde h é equivalente a g. No entanto, essa prática pode confundir o leitor do programa. Métodos podem chamar outros métodos utilizando o argumento sel f :

cl ass Bag:

def __i ni t __( sel f ) :

sel f . dat a = [ ]

def add( sel f , x) :

sel f . dat a. append( x)

def addt wi ce( sel f , x) :

sel f . add( x)

sel f . add( x)

Os métodos podem referenciar nomes globais da mesma forma que funções ordinárias. O escopo global associado a um método é o módulo contendo sua definição da classe (a classe propriamente dita nunca é usada como escopo global!). Ainda que seja raro encontrar a necessidade de utilizar dados globais num método, há diversos usos legítimos do escopo global. Por exemplo, funções e módulos importados no escopo global podem ser usados por métodos, bem como as funções e classes definidas no próprio escopo global. Provavelmente, a classe contendo o método em questão também foi definida neste escopo global.

Page 83: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Classes

83

Herança Obviamente, uma característica da linguagem não seria digna do nome “classe” se não suportasse herança. A sintaxe para uma classe derivada se parece com:

cl ass Der i vedCl assName( BaseCl assName) :

<st at ement - 1>

.

.

.

<st at ement - N>

O nome BaseCl assName deve estar definido em um escopo contendo a definição da classe derivada. No lugar do nome da classe base também são aceitas expressões. O que é muito útil quando a classe base é definida noutro módulo, ex:

cl ass Der i vedCl assName( modname. BaseCl assName) :

A execução de uma definição de uma classe derivada procede da mesma forma que a de uma classe base. Quando o objecto classe é construído, a classe base é lembrada. Isso é utilizado para resolver referências a atributos. Se um atributo requisitado não for encontrado na classe, ele é procurado na classe base. Essa regra é aplicada recursivamente se a classe base por sua vez for derivada de outra.

Não existe nada de especial sobre instanciação de classes derivadas. Der i vedCl assName( ) cria uma nova instância da classe. As referências a métodos são resolvidas da seguinte forma: o atributo correspondente é procurado através da cadeia de derivação, e referências a métodos são válidas desde que produzam um objecto do tipo função.

Classes derivadas podem sobrescrever métodos das suas classes base. Uma vez que métodos não possuem privilégios especiais quando invocam outros métodos no mesmo objecto, um método na classe base que invocava um outro método da mesma classe base, pode efectivamente acabar invocando um método sobreposto por uma classe derivada. Para programadores C++ isso significa que todos os métodos em Python são efectivamente vi r t ual .

Um método que subscreva outro numa classe derivada pode desejar na verdade estender, ao invés de substituir, o método sobrescrito de mesmo nome na classe base. A maneira mais simples de implementar esse comportamento é chamar directamente a classe base ‘BaseCl assName. met hodname( sel f , ar gument s) ’ . O que pode ser útil para os usuários da classe também. Note-se que isso só funciona se a classe base for definida ou importada directamente no escopo global.

Herança múltipla O Python também suporta uma forma limitada de herança múltipla. Uma definição de classe que herda de várias classes bases é:

cl ass Der i vedCl assName( Base1, Base2, Base3) :

<st at ement - 1>

Page 84: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

84

.

.

.

<st at ement - N>

A única regra que precisa ser explicada é a semântica de resolução para as referências a atributos de classes. É feita uma busca em profundidade da esquerda para a direita. Logo, se um atributo não é encontrado em Der i vedCl assName, ele é procurado em Base1, e recursivamente nas classes bases de Base1, e apenas se não for encontrado lá a busca prosseguirá em Base2, e assim sucessivamente.

Para algumas pessoas a busca em largura – procurar antes em Base2 e Base3 do que nos ancestrais de Base1 — parece mais natural. Entretanto, seria preciso conhecer toda a hierarquia de Base1 para evitar um conflito com um atributo de Base2. Enquanto a busca em profundidade não diferencia o acesso a atributos directos ou herdados de Base1.

É sabido que o uso indiscriminado de herança múltipla é o pesadelo da manutenção, sobretudo pela confiança do Python na adopção de uma convenção de nomenclatura para evitar conflitos. Um problema bem conhecido com herança múltipla é quando há uma classe derivada de outras que por sua vez possuem um ancestral em comum.

Ainda que seja perfeitamente claro o que acontecerá (a instância irá possuir uma única cópia dos atributos de dados do ancestral comum), não está claro se a semântica é útil.

Variáveis Privadas Existe um suporte limitado a identificadores privados em classes. Qualquer identificador no formato __spam (no mínimo dois caracteres ‘ ’ no prefixo e no máximo um como sufixo) é realmente substituído por classname_spam, onde cl assname é o nome da classe corrente. Essa construção independe da posição sintáctica do identificador, e pode ser usada para tornar privadas: instâncias, variáveis de classe e métodos. Pode haver truncamento se o nome combinado extrapolar 255 caracteres. Fora de classes, ou quando o nome da classe só tem ‘ ’ , não se aplica esta construção.

Este procedimento visa oferecer a classes uma maneira fácil de definir variáveis de instância e métodos “privados”, sem ter que se preocupar com outras variáveis de instância definidas em classes derivadas ou definidas fora da classe. Apesar da regra de nomenclatura ter sido projectada para evitar “acidentes”, ainda é possível o acesso e a manipulação de entidades privadas. O que é útil no caso dos “debugers” , talvez a única razão pela qual essa característica ainda não tenha sido suprimida (detalhe: derivar uma classe com o mesmo nome da classe base torna possível o uso de seus membros privados! Isso pode ser corrigido em versões futuras).

O código passado para exec , eval ( ) ou eval f i l e( ) não considera o nome da classe que o invocou como sendo a classe corrente. O modificador gl obal funciona de maneira semelhante, quando se está restrito ao código que foi byte-compilado em conjunto. A mesma restrição aplica-se aos comandos get at t r ( ) , set at t r ( ) e del at t r ( ) , e a manipulação directa do dicionário di ct .

Page 85: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Classes

85

Aqui está um exemplo de uma classe que implementa os seus próprios métodos get at t r ( ) e set at t r ( ) , armazenando todos os atributos em variáveis privadas. Da forma como foi codificado este exemplo, ele irá funcionar até em versões de Python em que esta característica ainda não havia sido implementada.

cl ass Vi r t ual At t r i but es:

__vdi ct = None

__vdi ct _name = l ocal s( ) . keys( ) [ 0]

def __i ni t __( sel f ) :

sel f . __di ct __[ sel f . __vdi ct _name] = { }

def __get at t r __( sel f , name) :

r et ur n sel f . __vdi ct [ name]

def __set at t r __( sel f , name, val ue) :

sel f . __vdi ct [ name] = val ue

Particularidades Às vezes, é útil ter um tipo semelhante ao “record” de Pascal ou ao “struct” de C. Uma definição de classe vazia atende esse propósito:

cl ass Empl oyee:

pass

j ohn = Empl oyee( ) # Cr i a um r egi st r o vazi o de Empr egado

# Pr eenche os campos do r egi st r o

j ohn. name = ’ John Doe’

j ohn. dept = ’ comput er l ab’

j ohn. sal ar y = 1000

Um código em Python que espera um tipo abstracto de dados em particular, pode receber ao invés do tipo abstracto uma classe (que emula os métodos que aquele tipo suporta). Por exemplo, se se tem uma função que formata dados num objecto arquivo, pode-se definir uma classe com os métodos r ead( ) e r eadl i ne( ) que utiliza um buffer ao invés do arquivo propriamente dito.

Os métodos de instância são objectos, e podem possuir atributos também.

As Excepções podem ser Classes Excepções definidas pelo usuário podem ser identificadas por classes. Através deste mecanismo é possível criar hierarquias extensíveis de excepções.

Existem duas novas semânticas válidas para o comando r ai se:

r ai se Cl ass, i nst ance

r ai se i nst ance

Na primeira forma, i nst ance deve ser uma instância de Cl ass ou de uma classe derivada dela. A segunda forma é um atalho para:

r ai se i nst ance. __cl ass__, i nst ance

Page 86: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

86

Uma cláusula de excepção pode listar tanto classes como strings. Uma classe numa cláusula de excepção é compatível com a excepção se é a mesma classe prevista na cláusula ou ancestral dela (não o contrário, se na cláusula estiver uma classe derivada não irá haver casamento com excepções base levantadas). No exemplo a seguir será impresso B, C, D nessa ordem:

cl ass B:

pass

c l ass C( B) :

pass

c l ass D( C) :

pass

f or c i n [ B, C, D] :

t r y :

r ai se c( )

except D:

pr i nt " D"

except C:

pr i nt " C"

except B:

pr i nt " B"

Se a ordem das cláusulas fosse invertida (B no início), seria impresso B, B, B – sempre a primeira cláusula válida é activada.

Quando uma mensagem de erro é impressa para uma excepção não tratada, que seja uma classe, o nome da classe é impresso, e depois a instância da excepção é convertida para string pela função st r ( ) e é também impressa (após um espaço e uma vírgula).

Page 87: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Conclusão

87

CCoonncclluussããoo

Page 88: WKRQ - Departamento de Engenharia Informáticapaf/proj/Set2001/python.pdf · Capítulo 1 Introdução 07 Breve ... Utilizando o Python como uma calculadora 18 Números 18 ... Tudo

Python

88

Conclusão

Python tem um papel de integração importante no desenvolvimento de grandes aplicações com uma probabilidade de vida longa. Permite uma resposta rápida nas mudanças das necessidades do utilizador, que requer uma adaptação da lógica da aplicação, sem mudar os componentes subjacentes fundamentais. Também, permite uma adaptação rápida da aplicação, a mudanças nos componentes subjacentes.

JPython (o futuro) Uma nova implementação do Python, escrito em 100% Java, denominado de JPython está correntemente a ser desenvolvido. JPython é uma implementação total da linguagem Python, que permite acesso directo às classes do Java. O código em Java também pode utilizar as classes do Python (isto é importante para “Callbacks” , por exemplo).

O argumento principal do JPython é: faz para o Java aquilo que o Python já fazia para o C/C++. A integração do JPython com o Java é superior à integração entre o Python e C++: devido ao efeito “Reflection API” do Java, JPython pode usar arbitrariamente classes do Java sem a ajuda de um gerador “wrapper” como o SWIG.