Você está na página 1de 40

Mergulhando no Python Dive Into Python

8 October 2003 Copyright 2000, 2001, 2002, 2003 Mark Pilgrim Este livro est disponvel em http://diveintopython.org/. Caso esteja lendo em algum outro lugar sua verso pode estar desatualizada . Permission is granted to copy, distribute, and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in GNU Free Documentation License. The example programs in this book are free software; you can redistribute and/or modify them under the terms of the Python license as published by the Python Software Foundation. A copy of the license is included in Python 2.1.1 license. Table of Contents

1. Instalando o Python 1.1. Qual Python o certo para voc? 1.2. Python em Windows 1.3. Python no Mac OS X 1.4. Python no Mac OS 9 1.5. Python no RedHat Linux 1.6. Python no Debian GNU/Linux 1.7. Instalando a partir do cdigo fonte 1.8. O interpretador interativo 1.9. Resumo 2. Conhecendo o Python 2.1. Mergulhando 2.2. Declarando funes 2.3. Documentando funes 2.4. Tudo objeto 2.5. Indentando cdigo 2.6. Testando mdulos 2.7. Apresentando dicionrios 2.8. Apresentando listas 2.9. Apresentando tuplas 2.10. Declarando variveis 2.11. Atribuindo mltiplos valores de uma vez 2.12. Formatando strings 2.13. Mapeando listas 2.14. Unindo listas e separando strings 2.15. Resumo 3. O poder da introspeco 3.1. Mergulhando 3.2. Argumentos opcionais e nomeados 3.3. type, str, dir, e outras funes internas 3.4. Extraindo referncias a objetos com getattr 3.5. Filtrando listas

3.6. A natureza peculiar de and e or

Chapter 1. Instalando o Python


1.1. Qual Python o certo para voc? 1.2. Python em Windows 1.3. Python no Mac OS X 1.4. Python no Mac OS 9 1.5. Python no RedHat Linux 1.6. Python no Debian GNU/Linux 1.7. Instalando a partir do cdigo fonte 1.8. O interpretador interativo 1.9. Resumo

1.1. Qual Python o certo para voc?


Bem-vindo ao Python. Vamos mergulhar. A primeira coisa que voc precisa fazer com Python instalar. Ou no? Se voc est usando uma conta hospedada em um provedor, Python pode j estar instalado. A maioria das distribuies Linux instala Python por padro. O Mac OS X 10.2 ou posterior j vem com uma verso linha de comando de Python, embora provavelmente voc queira escolher uma verso com uma interface grfica no estilo Mac. O Windows no vem com Python. Mas no se preocupe! H diversas formas fceis de entrar no mundo Python usando Windows. Como voc pode ver, Python roda em muitos sistemas operacionais. A lista completa inclui Windows, o Mac OS, o Mac OS X e todos os vrios sistemas gratuitos compatvel com UNIX como o prprio Linux. H tambm verses que rodam no Sun Solaris, AS/400, Amiga, OS/2, BeOS e muitas outras plataformas que voc provavelmente nunca ouviu falar. E o que melhor, programas Python escritos em uma plataforma podem, com um pouco de cuidado, rodar em qualquer plataforma suportada. Por exemplo, eu regularmente desenvolvo programas Python no Windows e mais tarde os executo no Linux. Voltando pergunta que abriu esta seo: qual Python o certo para voc? A resposta aquele que roda no computador que voc tem

1.2. Python em Windows


No Windows, voc tem diversas escolhas para instalar o Python. A ActiveState tem um instalador Python para Windows que inclui a verso completa do Python, um IDE com um editor de cdigo e extenses Windows para o Python que permitem acesso a servios especficos do Windows, suas APIs e o registro. O ActivePython pode ser baixado gratuitamente, mas no open source. Foi com ele que eu aprendi a usar Python, e recomendo que voc use a no ser que tenha algum motivo em particular para o evitar. (Um desses motivos pode ser o fato da ActiveState demorar alguns meses para atualizar o ActivePython com a ltima verso de Python disponvel. Se voc realmente precisa da ltima verso do Python e o ActivePython ainda est desatualizado, pule para a opo 2.)

Procedure 1.1. Opo 1: Instalando o ActivePython


1. Baixe o ActivePython em http://www.activestate.com/Products/ActivePython/. 2. Se voc usa Windows 95, Windows 98 ou Windows ME, deve instalar o Windows Installer 2.0 antes de continuar. 3. D um clique duplo no arquivo ActivePython-2.2.2-224-win32-ix86.msi. 4. Siga as instrues na tela. 5. Se seu espao em disco for limitado, possvel fazer uma instalao personalizada ("custom") e deixar de instalar a documentao, mas isso no recomendado a no ser que voc no realmente no possa gastar 14 megabytes a mais. 6. Aps o trmino da instalao, feche o instalador e abra Iniciar->Programas->ActiveState ActivePython 2.2->PythonWin IDE.

Example 1.1. IDE ActivePython


PythonWin 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32. Portions Copyright 1994-2001 Mark Hammond (mhammond@skippinet.com.au) see 'Help/About PythonWin' for further copyright information. >>>

A segunda opo usar o instalador Python oficial, distribudo pelos prprios desenvolvedores do Python. Esse instalador pode ser baixado gratuitamente, tem cdigo fonte aberto e est sempre atualizado.

Procedure 1.2. Opo 2: Instalando o Python do Python.org


1. Baixe o instalador Windows do Python em http://www.python.org/ftp/python/2.3.2/. 2. Execute o arquivo Python-2.3.2.exe. 3. Siga as instrues na tela. 4. Se seu espao em disco for limitado, possvel deselecionar o arquivo HTMLHelp, os scripts (Tools/), e/ou o kit de testes (Lib/test/). 5. Se voc no tem direitos administrativos, pode selecionar Advanced Options ... e selecionar NonAdmin Install. A nica diferena a forma como as entradas de registro e os atalhos de menus so criados. 6. Aps o trmino da instalao, feche o instalador e abra Iniciar->Programas->Python 2.3->IDLE (Python GUI).

Example 1.2. IDLE (GUI Python)


Python 2.3.2 (#49, Oct 2 2003, 20:02:00) [MSC v.1200 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. **************************************************************** Personal firewall software may warn about the connection IDLE makes to its subprocess using this computer's internal loopback interface. This connection is not visible on any external interface and no data is sent to or received from the Internet. **************************************************************** IDLE 1.0 >>>

1.3. Python no Mac OS X


No Mac OS X, voc tem duas opes: instalar ou no instalar. Voc provavelmente quer instalar. O Mac OS X 10.2 ou posterior vem com uma verso linha de comando do Python pr-instalada. Se voc usa confortavelmente a linha de comando, pode usar essa verso durante o primeiro tero desse livro. A verso pr-instalada no vem com um parser XML, ento quando chegar ao captulo sobre XML ser necessrio instalar a verso completa.

Procedure 1.3. Executando a verso pr-instalada do Python no Mac OS X


1. Abra a pasta /Applications. 2. Abra a pasta Utilities. 3. D um clique duplo no Terminal para abrir uma janela de terminal e chegar linha de comando. 4. Digite python na linha de comando.

Example 1.3. Usando a verso pr-instalada de Python no Mac OS X


Welcome to Darwin! [localhost:~] you% python Python 2.2 (#1, 07/14/02, 23:25:09) [GCC Apple cpp-precomp 6.14] on darwin Type "help", "copyright", "credits", or "license" for more information. >>> [aperte Ctrl+D para voltar ao prompt de comando] [localhost:~] you%

Isso funciona, mas provavelmente voc vai preferir instalar a ltima verso, que tambm vem com um interpretador grfico interativo.

Procedure 1.4. Instalando no Mac OS X


1. Baixe a imagem de disco MacPython-OSX em http://homepages.cwi.nl/~jack/macpython/download.html. 2. Se o browser no o fizer automaticamente, d um clique duplo no arquivo MacPython-OSX2.3-1.dmg para montar a imagem de disco no desktop. 3. D um clique duplo no instalador, MacPython-OSX.pkg. 4. O instalador pedir o nome de usurio e a senha do administrador. 5. Siga as instrues na tela. 6. Aps a instalao, feche o instalador e abra a pasta /Applications. 7. Abra a pasta MacPython-2.3 8. D um clique duplo em PythonIDE para executar o Python. O IDE MacPython deve mostrar uma tela de abertura e abrir um interpretador interativo. Caso o interpretador no aparea, selecione Window->Python Interactive (Cmd-0).

Example 1.4. O IDE MacPython no Mac OS X


Python 2.3 (#2, Jul 30 2003, 11:45:28)

[GCC 3.1 20020420 (prerelease)] Type "copyright", "credits" or "license" for more information. MacPython IDE 1.0.1 >>>

Note que mesmo instalando a verso mais nova, a verso pr-instalada continua presente. Se estiver rodando scripts a partir da linha de comando, voc precisa tomar cuidado com que verso de Python est usando.

Example 1.5. Duas verses de Python


[localhost:~] you% python Python 2.2 (#1, 07/14/02, 23:25:09) [GCC Apple cpp-precomp 6.14] on darwin Type "help", "copyright", "credits", or "license" for more information. >>> [aperte Ctrl+D para voltar ao prompt de comando] [localhost:~] you% /usr/local/bin/python Python 2.3 (#2, Jul 30 2003, 11:45:28) [GCC 3.1 20020420 (prerelease)] on darwin Type "help", "copyright", "credits", or "license" for more information. >>> [aperte Ctrl+D para voltar ao prompt de comando] [localhost:~] you%

1.4. Python no Mac OS 9


O Mac OS 9 no vem com qualquer verso de Python, mas a instalao simples e s h uma opo.

Procedure 1.5. Instalando no Mac OS 9


1. Baixe o arquivo MacPython23full.bin em http://homepages.cwi.nl/~jack/macpython/download.html. 2. Se seu browser no abrir o arquivo automaticamente, d um clique duplo no arquivo MacPython23full.bin para descomprimir o arquivo com o Stuffit Expander. 3. D um clique duplo no instalador, MacPython23full. 4. Siga as instrues na tela. 5. Aps o trmino da instalao, feche o instalador e abra a pasta /Application. 6. Abra a pasta MacPython-OS9 2.3. 7. D um clique duplo em Python IDE para executar o Python. O IDE MacPython IDE deve mostrar uma tela de abertura e um interpretador interativo. Caso o shell interativo no aparea, selecione Window->Python Interactive (Cmd-0).

Example 1.6. O IDE MacPython no Mac OS 9


Python 2.3 (#2, Jul 30 2003, 11:45:28) [GCC 3.1 20020420 (prerelease)] Type "copyright", "credits" or "license" for more information. MacPython IDE 1.0.1 >>>

1.5. Python no RedHat Linux


A instalao em sistemas operacionais compatveis com UNIX (como o Linux) fcil se voc usar um pacote binrio. Pacotes binrios pr-compilados esto disponveis para as distribuies Linux mais populares, ou voc pode compilar a partir do cdigo fonte. Para instalar no RedHat Linux, voc deve baixar o RPM em http://www.python.org/ftp/python/2.3.2/rpms/ e instalar usando o comando rpm.

Example 1.7. Instalando no RedHat Linux 9


localhost:~$ su Password: [digite sua senha de root] [root@localhost root]# wget http://python.org/ftp/python/2.3/rpms/redhat9/python2.3-2.3-5pydotorg.i386.rpm Resolving python.org... done. Connecting to python.org[194.109.137.226]:80... connected. HTTP request sent, awaiting response... 200 OK Length: 7,495,111 [application/octet-stream] ... [root@localhost root]# rpm -Uvh python2.3-2.3-5pydotorg.i386.rpm Preparing... ########################################### [100%] 1:python2.3 ########################################### [100%] [root@localhost root]# python Python 2.2.2 (#1, Feb 24 2003, 19:13:11) [GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-4)] on linux2 Type "help", "copyright", "credits", or "license" for more information. >>> [aperte Ctrl+D para sair] [root@localhost root]# python2.3 Python 2.3 (#1, Sep 12 2003, 10:53:56) [GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2 Type "help", "copyright", "credits", or "license" for more information. >>> [aperte Ctrl+D para sair] [root@localhost root]# which python2.3 /usr/bin/python2.3

Ops! Apenas digitando python executamos a verso velha do Python, que veio instalada por padro. No isso que queremos. A verso nova se chama python2.3. Voc provavelmente deve mudar o caminho na primeira linha dos scripts de exemplo para que aponte para a verso mais nova. Este o caminho completo da verso mais nova do Python que acabamos de instalar. Use isso na linha que comea com #! no comeo de seus scripts para garantir que os scripts sero executados com a verso mais recente do Python, e lembre-se sempre de executar python2.3 para entrar no interpretador interativo.

1.6. Python no Debian GNU/Linux


Se voc sortudo o suficiente para estar rodando o Debian GNU/Linux, a instalao feita com o comando apt.

Example 1.8. Instalando no Debian GNU/Linux


localhost:~$ su Password: [digite sua senha de root] localhost:~# apt-get install python Reading Package Lists... Done Building Dependency Tree... Done The following extra packages will be installed: python2.3 Suggested packages: python-tk python2.3-doc The following NEW packages will be installed: python python2.3 0 upgraded, 2 newly installed, 0 to remove and 3 not upgraded. Need to get 0B/2880kB of archives. After unpacking 9351kB of additional disk space will be used. Do you want to continue? [Y/n] Y Selecting previously deselected package python2.3. (Reading database ... 22848 files and directories currently installed.) Unpacking python2.3 (from .../python2.3_2.3.1-1_i386.deb) ... Selecting previously deselected package python. Unpacking python (from .../python_2.3.1-1_all.deb) ... Setting up python (2.3.1-1) ... Setting up python2.3 (2.3.1-1) ... Compiling python modules in /usr/lib/python2.3 ... Compiling optimized python modules in /usr/lib/python2.3 ... localhost:~# exit logout localhost:~$ python Python 2.3.1 (#2, Sep 24 2003, 11:39:14) [GCC 3.3.2 20030908 (Debian prerelease)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> [aperte Ctrl+D para sair]

1.7. Instalando a partir do cdigo fonte


Caso voc prefira compilar seu Python, baixe o cdigo fonte em http://www.python.org/ftp/python/2.3.2/ e faa o ritual de configure, make, make install.

Example 1.9. Instalando a partir do cdigo fonte


localhost:~$ su Password: [digite sua senha de root] localhost:~# wget http://www.python.org/ftp/python/2.3/Python-2.3.tgz Resolving www.python.org... done. Connecting to www.python.org[194.109.137.226]:80... connected. HTTP request sent, awaiting response... 200 OK Length: 8,436,880 [application/x-tar] ... localhost:~# tar xfz Python-2.3.tgz localhost:~# cd Python-2.3 localhost:~/Python-2.3# ./configure checking MACHDEP... linux2 checking EXTRAPLATDIR... checking for --without-gcc... no ... localhost:~/Python-2.3# make gcc -pthread -c -fno-strict-aliasing -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Modules/python.o Modules/python.c

gcc -pthread -c -fno-strict-aliasing -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/acceler.o Parser/acceler.c gcc -pthread -c -fno-strict-aliasing -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/grammar1.o Parser/grammar1.c ... localhost:~/Python-2.3# make install /usr/bin/install -c python /usr/local/bin/python2.3 ... localhost:~/Python-2.3# exit logout localhost:~$ which python /usr/local/bin/python localhost:~$ python Python 2.3.1 (#2, Sep 24 2003, 11:39:14) [GCC 3.3.2 20030908 (Debian prerelease)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> [aperte Ctrl+D para voltar ao prompt de comando] localhost:~$

1.8. O interpretador interativo


Agora que temos o Python instalado, o que esse tal de interpretador interativo? Funciona assim: o Python tem vida dupla. Ele pode ser usado como um interpretador de scripts que voc pode executar linha de comando ou dando um duplo clique neles como se fossem aplicaes. E tambm possvel us-lo como um interpretador interativo para avaliar expresses e comandos. Isso til para depurar, desenvolver rapidamente e executar testes. H at pessoas que usam o interpretador interativo como uma calculadora! Abra o interpretador interativo do Python da maneira como for necessrio em sua plataforma, e vamos mergulhar.

Example 1.10. Primeiros passos no interpretador interativo


>>> 1 + 1 2 >>> print 'hello world' hello world >>> x = 1 >>> y = 2 >>> x + y 3

O interpretador interativo do Python pode avaliar expresses Python arbitrrias, inclusive expresses aritmticas bsicas. O interpretador interativo pode executar comandos Python arbitrrios, inclusive o comando print. Voc pode atribuir valores a variveis, e os valores sero lembrados por quanto tempo o interpretador esteja aberto (e nada alm disso).

1.9. Resumo
Voc deve agora ter uma verso de Python que funciona.

Dependendo de sua plataforma, voc pode ter mais de uma. Caso seja seu caso, necessrio tomar cuidado com os caminhos dos interpretadores. Caso a simples execuo do comando python no abra a verso do Python que voc queira usar, pode ser necessrio digitar o caminho completo para a verso completa. Fora isso, parabns, e bem-vindo ao Python.

Chapter 2. Conhecendo o Python


2.1. Mergulhando 2.2. Declarando funes 2.3. Documentando funes 2.4. Tudo objeto 2.5. Indentando cdigo 2.6. Testando mdulos 2.7. Apresentando dicionrios 2.8. Apresentando listas 2.9. Apresentando tuplas 2.10. Declarando variveis 2.11. Atribuindo mltiplos valores de uma vez 2.12. Formatando strings 2.13. Mapeando listas 2.14. Unindo listas e separando strings 2.15. Resumo

2.1. Mergulhando
Aqui temos um programa Python completo. Provavelmente ele no faz o menor sentido para voc. No se preocupe ainda. Vamos apenas analislo, linha a linha. Mas leia o programa e veja se consegue entender algo.

Example 2.1. odbchelper.py


If you have not already done so, you can download this and other examples used in this book.
def buildConnectionString(params): """Build a connection string from a dictionary of parameters. Returns string.""" return ";".join(["%s=%s" % (k, v) for k, v in params.items()]) if __name__ == "__main__": myParams = {"server":"mpilgrim", \ "database":"master", \ "uid":"sa", \ "pwd":"secret" \ } print buildConnectionString(myParams)

Agora rode esse programa e veja o que acontece.

No ActivePython em Windows, o mdulo pode ser executado com File->Run... (Ctrl-R). A sada exibida na janela interativa. No IDE do Mac OS X, o mdulo pode ser executado em Python->Run window... (Cmd-R), mas h uma opo importante que voc deve verificar antes. Abra o mdulo no IDE, abra o menu de opes do mdulo clicando no tringulo preto no canto superior direito da janela, e verifique que a opo Run as __main__ esteja marcada. Essa configurao guardada com o mdulo, portanto s precisa ser feita uma vez por mdulo. Em sistemas compatveis com UNIX (incluindo Mac OS X), possivel executar um mdulo da linha de comando: python odbchelper.py

Example 2.2. Sada de odbchelper.py


server=mpilgrim;uid=sa;database=master;pwd=secret

2.2. Declarando funes


O Python tem funes como a maioria das linguagens, mas no tem arquivos de cabealho separados como C++ ou sees interface e implementation como Pascal. Quando precisar de uma funo, apenas declare e saia programando.

Example 2.3. Declarando a funo buildConnectionString


def buildConnectionString(params):

Vrias coisas devem ser notadas. Em primeiro lugar, a palavra-chave def inicia uma declarao de funo, seguida pelo seu nome, seguido pelos argumentos entre parnteses. Mltiplos argumentos (no o caso aqui) podem ser separados por vrgulas. A funo no define um tipo de dado de retorno. Funes Python no especificam o tipo de seu valor de retorno; nem sequer se especifica se de fato existe um valor de retorno. Caso a funo execute um comando return, retornar um valor, e caso contrrio retornar None, o valor nulo padro do Python. Em Visual Basic, funes (que retornam valor) comeam com function, e subrotinas (que no retornam um valor) comeam com sub. No h subrotinas em Python, apenas funes. Todas as funes retornam um valor (mesmo que seja None), e todas as funes so declarads com def. O argumento, params, no especifica um tipo de dado. Em Python, variveis nunca so explicitamente tipadas. Python descobre qual o tipo da varivel e toma conta disso internamente. Em Java, C++ e outras linguagens de tipagem esttica necessrio especificar o tipo do valor de retorno e de cada argumento de funo. Em Python, o tipo de dados nunca explicitamente declarado. O Python toma conta do tipo internamente baseado no valor que voc atribuir. Adendo. Um leitor erudito enviou essa explicao de como Python se compara com outras linguagens: linguagens estaticamente tipadas Linguagens em que os tipos so definidos em tempo de compilao. A maior parte das linguagens estaticamente tipadas fora isso obrigando que todas as variveis sejam declaradas

com tipos definidos antes que possam ser usadas. Java e C so linguagens estaticamente tipadas. linguagens dinamicamente tipadas Linguagens em que os tipos so descobertos em tempo de execuo; o oposto das linguagens estaticamente tipadas. VBScript e Python so dinamicamente tipadas, porque descobrem o tipo da varivel quando voc atribui um valor mesma. linguagens fortemente tipadas Linguagens em que os tipos so sempre estritamente seguidos. Java e Python so fortemente tipadas. Se voc tem um inteiro, no pode tratar como se fosse uma string sem converso explcita (mais sobre esse assunto mais adiante nesse captulo). linguagens fracamente tipadas Linguagens em que o tipo ignorado; o oposto das linguagens fortemente tipadas. VBScript fracamente tipado. Em VBScript, possivel concatenar a string '12' como o inteiro 3 e ter como resultado a string '123', que tambm pode ser usada como se fosse o inteiro 123, tudo isso sem converso explcita. Portanto Python tanto dinamicamente tipada (porque no requer declaraes de tipo) e fortemente tipada (porque a partir do momento em que a varivel tem tipo, esse tipo faz diferena).

2.3. Documentando funes


possivel documentar uma funo do Python usando uma doc string.

Example 2.4. Definindo a doc string de buildConnectionString


def buildConnectionString(params): """Build a connection string from a dictionary of parameters. Returns string."""

Trs aspas duplas limitam uma string multi-linhas. Tudo entre os aspas iniciais e finais faz parte da string, inclusive quebras de linha e outros tipos de aspas. possvel usar strings multi-linhas em qualquer lugar, mas a maior parte das vezes ser na definio de uma doc string. Aspas triplas so uma maneira til de definir uma string com aspas simples e duplas, como qq/.../ em Perl. Tudo entre as triplas aspas a doc string da funo, a documentao do que a funo faz. Uma doc string, caso exista, deve ser a primeira coisa definida em uma funo (i.e. a primeira coisa depois do dois-pontos). No tecnicamente obrigatrio usar uma doc string, mas uma boa idia. Eu sei que voc deve ter ouvido isso todas as aulas de programao que voc j teve, mas Python tem um incentivo a mais: a doc string est disponvel em tempo de execuo como um atributo da funo. Muitos IDEs Python usam a doc string para prover documentao sensvel ao contexto, de forma que quando voc digita o nome da funo a doc string aparece como uma dica flutuante. Isso muito til, mas apenas to bom quanto as doc strings que voc escreve.

Leitura recomendada

PEP 257 define convenes de doc string.

Python Style Guide discute como escrever uma boa doc string. Python Tutorial discute convenes de espaamento em doc strings.

2.4. Tudo objeto


Caso voc no tenha prestado ateno, eu disse que funes Python tm atributos, e que estes atributos esto disponveis em tempo de execuo. Uma funo, como tudo em Python, objeto.

Example 2.5. Acessando a doc string da funo buildConnectionString


>>> import odbchelper >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> print odbchelper.buildConnectionString(params) server=mpilgrim;uid=sa;database=master;pwd=secret >>> print odbchelper.buildConnectionString.__doc__ Build a connection string from a dictionary Returns string.

A primeira linha importa o programa odbchelper como um mdulo. Uma vez que se importe o mdulo, possivel fazer referncia a qualquer das funes, classes ou atributos pblicos. Mdulos podem podem fazer isso para fazer uso de recursos de outros mdulos, e voc pode fazer isso no IDE tambm. Esse conceito importante, e retornaremos a ele mais tarde. Quando voc quiser usar funes definidas em mdulos importados, deve incluir o nome do mdulo. Voc no pode dizer apenas buildConnectionString, obrigatrio usar odbchelper.buildConnectionString. Isto parecido com classes em Java. Ao invs de chamar a funo como poderia ser esperado, pedimos um dos atributos da funo, chamado __doc__. import em Python como require em Perl. Uma vez que voc import um mdulo Python, pode acessar seu contedo com mdulo.funo assim como em Perl voc importa com require e acessa com mdulo::funo. Antes de prosseguir, quero mencionar brevemente o caminho de busca de bibliotecas. O Python procura em diversos lugares o mdulo a ser importado. Mais especificamente, ele procura em todos os diretrios definidos em sys.path. O contedo dessa varivel uma lista, e voc pode facilmente visualizar ou modificar seu contedo com os mtodos de manipulao de lista, que veremos mais tarde nesse captulo.

Example 2.6. Caminhos de busca de mdulos


>>> import sys >>> sys.path ['', '/usr/local/lib/python2.2', '/usr/local/lib/python2.2/plat-linux2', '/usr/local/lib/python2.2/lib-dynload', '/usr/local/lib/python2.2/site-packages', '/usr/local/lib/python2.2/site-packages/PIL', '/usr/local/lib/python2.2/sitepackages/piddle'] >>> sys <module 'sys' (built-in)> >>> sys.path.append('/meu/novo/diretrio')

Importar o mdulo sys faz todas as suas funes e atributos ficarem disponveis para uso. sys.path uma lista de nomes de diretrio que define o caminho de busca atual. (O seu sys.path vai ser diferente, dependendo do sistema operacional, da verso de Python e de onde foi instalado.) O Python procura em todos esses diretrios, na ordem, por arquivos .py com o mesmo nome que o mdulo que voc est tentando importar. Na verdade, eu menti: a verdade um pouco mais complicada. Nem todos os mdulos so arquivos .py. Alguns, como o prprio mdulo sys, so mdulos "embutidos" ("built-in"): eles fazem parte do prprio Python. Mdulos embutidos funcionam como mdulos normais, mas o cdigo Python deles no est disponvel, porque no foram escritos em Python (o mdulo sys escrito em C). Voc pode adicionar um novo diretrio ao caminho de procura em tempo de execuo adicionando o nome do diretrio ao sys.path. O Python automaticamente far a procura no novo diretrio quando voc importar um mdulo. O efeito dura por tanto tempo quanto o Python esteja procurando. (Falaremos sobre o append e outros mtodos de lista mais tarde nesse captulo.) Tudo em Python objeto, e quase tudo tem atributos e mtodos.[1] Todas as funes tm um atributo interno __doc__, que retorna a doc string definida no cdigo fonte da funo. O mdulo sys um objeto que (entre outras coisas) um atributo chamado path, e assim por diante. Isto to importante que vou repetir mais uma vez caso voc no tenha entendido ainda: tudo em Python objeto. Strings so objetos. Listas so objetos. Funes so objetos. At mdulos so objetos.

Leitura recomendada

Python Reference Manual explica exatamente o que significa dizer que tudo em Python objeto porque algumas pessoas so pedantes e adoram discutos extensivamente esse tipo de coisa. eff-bot sumariza objetos Python.

Footnotes
[1] Diferentes linguagens

definem objeto de diferentes formas. Em algumas, significa que todos os objetos precisam ter atributos e mtodos. Em outras, significa que todos os objetos so herdveis FIXME. Em Python a definio mais relaxada: alguns objetos no tm atributos nem mtodos (mais sobre isso nesse captulo), e nem todos os objetos so herdveis (mais sobre isso no captulo 3). Mas tudo um objeto no sentido de que pode ser usado como valor de uma varivel ou passado como argumento para uma funo (mais sobre isso no captulo 2).

2.5. Indentando[2] cdigo


Funes Python no tm marcaes explcitas de comeo e fim como begin e end ou chaves. O nico delimitador o sinal de dois-pontos (:) e a prpria indentao do cdigo.

Example 2.7. Indentando a funo buildConnectionString


def buildConnectionString(params): """Build a connection string from a dictionary of parameters. Returns string.""" return ";".join(["%s=%s" % (k, v) for k, v in params.items()])

Blocos de cdigo (funes, comandos if, laos for, etc.) so definidos pelo uso de indentao. Indentar o cdigo inicia um bloco, remover a indentao termina. No h sinais especficos ou palavras-chave. Isso significa que espao em branco significativo e deve ser consistente. Nesse exemplo, o cdigo da funo (incluindo a doc string) est indentado com 4 espaos. No necessrio que seja 4, apenas que seja consistente. A primeira linha no indentada aps isso est fora da funo. Aps alguns protestos iniciais e vrias analogias cnicas com Fortran, voc far as pazes com esse recurso e comear a ver os benefcios. Um grande benefcio que todos os programas Python so parecidos, uma vez que indentao um requerimento da linguagem e no uma questo de estilo. Isso torna mais fcil a leitura de cdigo escrito por terceiros. Python usa quebras de linha para separar comandos e dois-pontos e indentao para separar cdigos de bloco. C++ e Java usam ponto-e-vrgula para separar comandos e chaves para separar blocos de cdigo.

Leitura recomendada

Python Reference Manual discute questes de indentao entre plataformas diferentes e mostra vrios erros de indentao. Python Style Guide discute estilo de indentao.

Footnotes
[2] Isso

um anglicismo mas os programadores falam assim (N. do T.)

2.6. Testando mdulos


Mdulos Python so objetos e tm diversos atributos teis. Voc pode usar isso para testar seus mdulos facilmente medida que os escreve.

Example 2.8. O truque do if __name__


if __name__ == "__main__":

Primeiro algumas observaes antes de atacar o ncleo da questo. Em primeiro lugar, parnteses no so obrigatrios em torno da expresso if. Alm disso, o comando if termina com dois-pontos, e seguido por cdigo indentado. Como C, Python usa == para comparao e = para atribuio. Ao contrrio de C, Python no aceita atribuio em-linha, o que torna impossvel fazer uma atribuio de valor quando voc queria fazer uma comparao. Ento por que esse if em particular um truque? Mdulos so objetos, e todos os mdulos tm um atributo interno chamado __name__. O valor desse atributo depende da forma como voc est usando o mdulo. Se voc usar import, o __name__ ser o nome de arquivo do mdulo, sem o caminho e sem a extenso. Mas tambm possvel executar um mdulo diretamente como um programa interativo. Nesse caso, __name__ ter o valor especial __main__.

Example 2.9. O __name__ de um mdulo importado


>>> import odbchelper >>> odbchelper.__name__ 'odbchelper'

Sabendo isso, voc pode criar um conjunto de testes para seu mdulo dentro do prprio mdulo, protegido por esse if. Quando voc executar o mdulo diretamente, __name__ ser __main__, e os testes sero executados. Quando importar o mdulo, __name__ ser alguma outra coisa e os testes sero ignorados. Com isso mais fcil desenvolver e depurar novos mdulos antes de integrlos a um programa maior. No MacPython h um passo adicional para fazer o truque do if __name__ funcionar. Abra o menu de opes do mdulo clicando o tringulo preto no canto superior direito da janela, e certifique-se de que Run as __main__ esteja selecionado.

Leitura recomendada

Python Reference Manual discute os detalhes de baixo nvel da importao de mdulos .

2.7. Apresentando dicionrios


Uma breve digresso necessria, porque voc precisa aprender sobre dicionrios, tuplas e listas (tudo isso!). Caso voc seja um programador Perl, pode apenas dar uma olhada nos dicionrios e listas, mas deve prestar ateno nas tuplas. Um dos tipos bsicos do Python o dicionrio, que define relaes um-para-um entre chaves e valores. Um dicionrio em Python como um hash (ou array associativo) em Perl. Em Perl, variveis que armazenam hashes sempre iniciam com um caracter %; em Python, variveis podem ter qualquer nome, e o tipo do dado mantido internamente. Um dicionrio em Python como uma instncia da classe Hashtable em Java. Um dicionrio em Python como a instncia de um objeto Scripting.Dictionary em Visual Basic.

Example 2.10. Definindo um dicionrio


>>> d = {"server":"mpilgrim", "database":"master"} >>> d {'server': 'mpilgrim', 'database': 'master'} >>> d["server"] 'mpilgrim' >>> d["database"] 'master' >>> d["mpilgrim"] Traceback (innermost last): File "<interactive input>", line 1, in ? KeyError: mpilgrim

Primeiramente, criamos um dicionrio com dois elementos e o atribumos varivel d. Cada elemento um par chave-valor, e o conjunto dos elementos limitado por chaves. 'server' uma chave, e seu valor associado, referenciado com d["server"], 'mpilgrim'. 'database' uma chave, e seu valor associado, referenciado com d["database"], 'master'. possvel achar os valores a partir da chave, mas no as chaves a partir do valor. Portanto d ["server"] 'mpilgrim', mas d["mpilgrim"] levanta uma exceo porque 'mpilgrim' no uma chave.

Example 2.11. Modificando um dicionrio


>>> d {'server': 'mpilgrim', 'database': 'master'} >>> d["database"] = "pubs" >>> d {'server': 'mpilgrim', 'database': 'pubs'} >>> d["uid"] = "sa" >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'pubs'}

No possvel ter chaves duplicadas em um dicionrio. Atribuir um valor a uma chave vai apagar o valor antigo. possvel adicionar pares chave-valor a qualquer momento. A sintaxe idntica de modificao de valores existentes. (Sim, isso vai incomodar voc algum dia quando voc achar que est adicionando valores mas est na verdade apenas modificando o mesmo valor porque uma chave no est mudando da forma como voc espera.) Note que o novo elemento (chave 'uid', valor 'sa') parece estar no meio. Na metade, apenas uma coincidncia os elementos terem aparecido em ordem no primeiro elemento; aqui apenas uma coincidncia que parea estar fora de ordem. Dicionrios no tm o conceito de ordenamento entre os elementos. incorreto dizer que os elementos esto fora de ordem; eles esto simplesmente desordenados. Essa distino importante e vai incomodar voc quando voc quiser acessar um dicionrio em uma ordem especfica, reproduzvel (como por ordem alfabtica de chave). H maneiras de fazer isso, mas no dentro do objeto de dicionrio.

Example 2.12. Misturando tipos em um dicionrio


>>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'pubs'} >>> d["retrycount"] = 3 >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 'retrycount': 3} >>> d[42] = "douglas" >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 42: 'douglas', 'retrycount': 3}

Dicionrios no so apenas para strings. Valores de dicionrios podem ter qualquer tipo, inclusive strings, inteiros, objetos e at outros dicionrios. E dentro de um dicionrio os valores no precisam ser de um tipo uniforme. possvel usar os tipos que forem necessrios, vontade. Chaves de dicionrios so mais restritivas, mas podem ser inteiros, strings e alguns outros tipos (mais sobre isso adiante). Os tipos de chaves tambm podem ser misturados.

Example 2.13. Removendo itens de um dicionrio


>>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 42: 'douglas', 'retrycount': 3} >>> del d[42] >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 'retrycount': 3} >>> d.clear() >>> d {}

del remove itens individuais do dicionrio por chave. clear remove todos os itens de um dicionrio. Note que um par de chaves vazio significa um dicionrio sem itens.

Example 2.14. Strings so sensveis a caso


>>> d = {} >>> d["key"] = >>> d["key"] = >>> d {'key': 'other >>> d["Key"] = >>> d {'Key': 'third "value" "other value" value'} "third value" value', 'key': 'other value'}

Atribuir um valor a uma chave existente de dicionrio simplesmente substitui o valor antigo com o novo. Isso no atribuir um valor novo a uma chave existente porque strings no Python so sensveis a caso, ento 'key' no o mesmo que 'Key'. Isso cria um novo par de chave/valor no dicionrio. Pode ser parecido para voc, mas para o Python algo totalmente diferente.

Leitura recomendada

How to Think Like a Computer Scientist ensina como usar dicionrios e como usar dicionrios para modelar matrizes esparsas. Python Knowledge Base Tem muitos exemplos de uso de dicionrios. Python Cookbook discute como ordenar valores de um dicionrio por chave. Python Library Reference sumariza todos os mtodos de dicionrios.

2.8. Apresentando listas


Listas so o tipo mais produtivo do Python. Se sua nica experincia com listas for arrays[3] em Visual Basic ou (coitado de voc) o datastore em Powerbuilder, prepare-se psicologicamente para aprender sobre as listas do Python.

Uma lista em Python como um array em Perl. Em Perl, variveis que armazenam arrays sempre comeam c variveis podem ter qualquer nome, uma vez que o Python cuida do tipo internamente.

Uma lista em Python faz muito mais que um array em Java (embora possa ser usada da mesma forma se tud melhor seria com a classe Vector, que pode armazenar objetos arbitrrios e crescer automaticamente med

Example 2.15. Definindo uma lista


>>> li = ["a", "b", "mpilgrim", "z", "example"] >>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[0] 'a' >>> li[4] 'example'

Primeiramente definimos uma lista com 5 elementos. Note que eles mantm a ordem original. Isso no obra d ordenado de elementos colocados entre colchetes. Uma lista pode ser usada como um array com ndice iniciado em zero. O primeiro elemento de uma lista no-va O ltimo elemento dessa lista de cinco elementos li[4], uma vez que listas tm ndice comeado em zero.

Example 2.16. ndices negativos de listas


>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[-1] 'example' >>> li[-3] 'mpilgrim'

Um ndice negativo acessa elementos a partir do fim da lista, contando para trs. O ltimo elemento de uma list Se ndices negativos esto criando confuso, pense dessa forma: li[-n] == li[len(li) - n]. Portant - 3] == li[2].

Example 2.17. Fatiando uma lista


>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[1:3] ['b', 'mpilgrim'] >>> li[1:-1] ['b', 'mpilgrim', 'z'] >>> li[0:3] ['a', 'b', 'mpilgrim']

Aqui tiramos um subconjunto da lista, chamado de fatia, especificando dois ndices. O valor de retorno uma elementos da lista, em ordem, a partir do primeiro ndice da fatia (nesse caso li[1]) at o segundo ndice, exc O fatiamento tambm funciona se um ou ambos os ndices forem negativos. Voc pode pensar da seguinte form direita, o primeiro ndice especifica o primeiro elemento que voc quer, e o segundo ndice especifica o primeir valor de retorno tudo que estiver no meio. Listas so baseadas em zero, portando li[0:3] retorna os trs primeiros elementos da lista, iniciando em li[

Example 2.18. Atalho no fatiamento


>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[:3]

['a', 'b', 'mpilgrim'] >>> li[3:] ['z', 'example'] >>> li[:] ['a', 'b', 'mpilgrim', 'z', 'example']

Se o primeiro ndice da fatia for 0, possvel deixar ele de fora. li[:3] o mesmo que li[0:3] do exempl De maneira semelhante, se o segundo ndice da fatia for o ltimo tem da lista, possvel deixar esse ndice fora li[3:5] porque a lista tem 5 elementos. Perceba a simetria aqui. Nessa lista de 5 elementos, li[:3] retorna os trs primeiros elementos, e li[3:] re [:n] sempre retorna n primeiros elementos, e li[n:] sempre retorna o restante, no importa o tamanho da li Se ambos os ndices da fatia so deixados de fora, todos os os elementos da lista so inclusos. Mas o resultado n sim uma outra lista que contm todos os elementos iguais. li[:] um atalho para fazer uma cpia completa d

Example 2.19. Adicionando elementos lista


>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li.append("new") >>> li ['a', 'b', 'mpilgrim', 'z', 'example', 'new'] >>> li.insert(2, "new") >>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new'] >>> li.extend(["two", "elements"]) >>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']

append adiciona um nico elemento ao fim da lista. insert insere um elemento em uma lista. O argumento numrico o ndice do primeiro elemento a ser empur atual. Note que elementos da lista no precisam ser nicos; h agora dois elementos distintos com o valor 'new extend concatena listas. Note que no se chama extend com mltiplos argumentos; o nico argumento um elementos.

Example 2.20. Buscando em uma lista


>>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements'] >>> li.index("example") 5 >>> li.index("new") 2 >>> li.index("c") Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: list.index(x): x not in list >>> "c" in li 0

index encontra a primeira ocorrncia de um valor na lista e retorna o ndice. index encontra a primeira ocorrncia de valor na lista. Nesse caso, 'new' ocorre duas vezes na lista, em li[ apenas o primeiro ndice, 2.

Se o valor no for encontrado na lista, o Python levanta uma exceo. Isso diferente da maioria das outras ling invlido. Embora possa parecer incmodo, isso a Coisa Certa, pois significa que seu programa vai ser interrom invs de mais tarde quando voc tentar usar o ndice invlido. Para testar se um valor est na lista, use in, que retorna 1 se o valor for encontrado ou 0 caso contrrio.

Antes da verso 2.2.1, Python no tinha um tipo de dados booleano. Para compensar essa falta, Python aceita contexto booleano (o condicional de um comando if por exemplo), de acordo com as seguintes regras: 0 fa verdadeiros. Uma string vazia ("") falsa, todas as demais strings so verdadeiras. Uma lista vazia ([]) fa verdadeiras. Uma tupla vazia (()) falsa, todas as outras tuplas so verdadeiras. Um dicionrio vazio ({}) so verdadeiro. Essas regras ainda funcionam assim do Python 2.2.1 em diante, mas agora tambm possve com os nomes de True e False. Note que ambos os valores comeam com maisculas: Python sensvel a

Example 2.21. Removendo elementos de uma lista


>>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements'] >>> li.remove("z") >>> li ['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements'] >>> li.remove("new") >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements'] >>> li.remove("c") Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: list.remove(x): x not in list >>> li.pop() 'elements' >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two']

remove remove a primeira ocorrncia de um valor em uma lista. remove remove apenas a primeira ocorrncia do valor. Nesse caso, 'new' aparecia duas vezes na lista, mas l apenas a primeira ocorrncia. Se o valor no for encontrado na lista, o Python levanta uma exceo. Isso simtrico com o comportamento do pop uma coisa interessante. Ele faz duas coisas: remove o ltimo elemento da lista e retorna o valor. Note qu retorna um valor mas no muda a lista, e diferente de li.remove(valor), que muda a lista mas no retorna

Example 2.22. Operadores de lista


>>> li = ['a', 'b', 'mpilgrim'] >>> li = li + ['example', 'new'] >>> li ['a', 'b', 'mpilgrim', 'example', 'new'] >>> li += ['two'] >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two'] >>> li = [1, 2] * 3 >>> li [1, 2, 1, 2, 1, 2]

Listas podem ser concatenadas com o operador +. lista = lista + outralista produz o mesmo resu (outralista). Mas o operador + retorna uma nova lista (concatenada) como valor, enquanto extend apen Isto significa que extend mais rpido, especialmente para listas grandes.

Python suporta o operador +=. li += ['two'] equivalente a li.extend(['two']). O operador += e pode ser sobrecarregado para funcionar com classes definidas pelo usurio. (Mais sobre classes no captulo 3. O operador * funciona em listas como um repetidor. li = [1, 2] * 3 equivalente a li = [1, 2] + concatena as tres listas em uma. FIXME (* cria referencias a mesma lista)

Leitura recomendada

How to Think Like a Computer Scientist fala sobre listas e ensina coisas importantes sobre o uso de listas como argumento de funes. Python Tutorial mostra como usar listas como pilhas e filas. Python Knowledge Base responde perguntas comuns sobre listas e tem bastantes exemplos de cdigo usando listas. Python Library Reference sumariza todos os mtodos de listas.

Footnotes
[3] Traduzido,

o termo array seria na maior parte dos casos um vetor. O termo array mais usual. (N.

do T.)

2.9. Apresentando tuplas


Uma tupla uma lista imutvel. Tuplas no podem ser alteradas depois de criadas.

Example 2.23. Definindo uma tupla


>>> t = ("a", "b", "mpilgrim", "z", "example") >>> t ('a', 'b', 'mpilgrim', 'z', 'example') >>> t[0] 'a' >>> t[-1] 'example' >>> t[1:3] ('b', 'mpilgrim')

Uma tupla definida da mesma forma que uma lista, exceto que o conjunto de elementos deve estar entre parnteses, no colchetes. Os elementos de uma tupla tm uma ordem definida, igual a listas. ndices de tuplas tambm so baseados em zero. Por isso, o primeiro elemento de uma tupla no-vazia sempre t[0]. ndices negativos so contados a partir do fim da tupla, como nas listas. Fatiar tuplas tambm funciona. Note que quando uma lista fatiada, o resultado uma lista, e quando uma tupla fatiada o resultado uma nova tupla.

Example 2.24. Tuplas no tm mtodos


>>> t ('a', 'b', 'mpilgrim', 'z', 'example') >>> t.append("new") Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'append'

>>> t.remove("z") Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'remove' >>> t.index("example") Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'index' >>> "z" in t 1

No possvel adicionar elementos a uma tupla. Tuplas no tm mtodos append ou extend. No possvel remover elementos de uma tupla. No existem os mtodoso remove ou pop. No possive achar elementos na lista com o mtodo index pois ele no existe.. possvel, porm, usar in para ver se um elemento existe na tupla. Ento para que servem as tuplas?

Tuplas so mais rpidas que listas. Se voc est definindo um conjunto constante de valores e tudo que voc vai fazer iterar por eles, use uma tupla ao invs de uma lista. Seu cdigo fica mais seguro caso voc proteja dados que no precisam ser mudados contra gravao. Usar uma tupla como usar um comando assert implcito dizendo que o dado apenas para leitura, e que bom pensar melhor antes de mudar isso. Lembra-se quando eu disse que chaves de dicionrios podem ser inteiros, strings e outros tipos? Tuplas so um desses tipos. Tuplas podem ser usadas como chaves de dicionrios, mas listas no.[4] Tuplas so usadas na formatao de strings, como veremos brevemente.

Tuplas podem ser convertidas em listas e vice-versa. A funo interna tuple toma uma lista como parmetro e retorna uma tupla com os mesmos elementos, e a funao list toma uma tupla e retorna uma lista. Uma maneira de pensar isso que tuple congela uma lista, list descongela uma tupla.

Leitura recomendada

How to Think Like a Computer Scientist ensina sobre tuplas e mostra como concatenar tuplas. Python Knowledge Base mostra como ordenar uma tupla. Python Tutorial mostra como definir uma tupla com um elemento.

Footnotes
[4] Na

verdade mais complicado que isso. Chaves de dicionrios devem ser imutveis. Tuplas so imutveis, mas se voc tiver tuplas de listas o tipo mutvel e no seguro us-las como chaves. Apenas tuplas de strings, nmeros ou outras tuplas seguras podem ser usadas como chaves de dicionrios.

2.10. Declarando variveis


Agora que voc acha que sabe tudo sobre dicionrios, tuplas e listas, vamos voltar ao nosso programaexemplo, odbchelper.py. Python tem variveis locais e globais como a maioria das outras linguagens, mas no h declaraes

explcitas de variveis. Variveis passam a existir quando um valor lhes atribudo e deixam de existir quando saem de escopo. .

Example 2.25. Definindo a varivel myParams


if __name__ == "__main__": myParams = {"server":"mpilgrim", \ "database":"master", \ "uid":"sa", \ "pwd":"secret" \ }

Vrias coisas interessantes aqui. Em primeiro lugar, note a indentao. Um comando if um cdigo de bloco e precisa ser indentado como uma funo. Em segundo lugar, a atribuio de variveis um comando espalhado por vrias linhas, com uma barra invertida (\) servindo como marcador de continuao. Quando um comando separado em vrias linhas com o sinal de continuao, (\), as linhas continuadas podem ser indentadas de qualquer maneira; as regras usuais de indentao do Python no se aplicam. Mas se seu IDE Python auto-indenta a linha continuada, aceite o padro a no ser que haja algum bom motivo contra. Estritamente falando, expresses entre parnteses, colchetes ou chaves (como na definio de um dicionrio) podem ser separadas em vrias linhas com ou sem o caracter de continuao (\). Eu gosto de incluir a barra invertida mesmo quando no obrigatria porque eu acho que deixa o cdigo mais fcil de ler, mas uma questo de etilo. Em terceiro lugar, voc nunca declarou a varivel myParams, voc apenas atribuiu um valor a ela. Funciona da mesma forma que VBScript sem a opo option explicit. Felizmente, ao contrrio de VBScript, Python no permite uma referncia a uma varivel que nunca teve um valor atribudo. A tentativa de fazer isso levanta uma exceo.

Example 2.26. Referncia a varivel no atribuda


>>> x Traceback (innermost last): File "<interactive input>", line 1, in ? NameError: There is no variable named 'x' >>> x = 1 >>> x 1

Voce vai agradecer ao Python por isso.

Leitura recomendada

Python Reference Manual mostra exemplos de quando voc pode deixar de usar o caracter continuador e quando voc obrigado a usar.

2.11. Atribuindo mltiplos valores de uma vez


Um dos atalhos mais interessantes em Python usar seqncias para atribuir mltiplos valores de uma

s vez.

Example 2.27. Atribuindo mltiplos valores de uma vez


>>> >>> >>> 'a' >>> 'b' >>> 'e' v = ('a', 'b', 'e') (x, y, z) = v x y z

v uma tupla de trs elementos, e (x, y, z) uma tupla de trs variveis. Atribuir um ao outro atribui os valores de v a cada uma das variveis, em ordem. Isso tem vrias utilidades. Eu freqentemente tenho que atribuir nomes a uma seqencia de valores. Em C, possvel usar enum e listar manualmente cada constante e seu valor associado, o que particularmente entendiante quando os valores so consecutivos. Em Python, possvel usar a funo embutida range com atribuies mltiplas para rapidamente atribuir valores consecutivos

Example 2.28. Assigning consecutive values


>>> [0, >>> >>> 0 >>> 1 >>> 6 range(7) 1, 2, 3, 4, 5, 6] (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7) MONDAY TUESDAY SUNDAY

A funo embutida range retorna uma lista de inteiros. Em sua forma mais simples, ela recebe um limite superior como parmetro e retorna uma lista iniciada em 0 com todos os inteiros at o valor do parmetro, exclusive. (Se quiser, possvel passar mais parmetros para especificar um valor inicial diferente de 0 e um incrementador diferente de 1. Voce pode usar print range.__doc__ para ver detalhes.) MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY e SUNDAY so variveis que estamos definindo. (Esse exemplo vem do mdulo calendar, um mdulo interessante que imprime calendrios da mesma forma que o comando UNIX cal. O mdulo calendar define constantes inteiras para os dias da semana.) Agora cada varivel tem seu valor: MONDAY vale 0, TUESDAY vale 1, etc. possvel usar atribuies de mltiplos valores para construir funes que retornam mltiplos valores, simplesmente retornando uma tupla com todos os valores. Quem chama a funo pode trat-la como uma tupla, ou atribuir valores a variveis individuais. Vrias bibliotecas Python padro fazem isso, inclusive o mdulo os, que discutiremos no captulo 3.

Leitura recomendada

How to Think Like a Computer Scientist mostra como usar atribuies de mltiplos valores para trocar os valores de duas variveis.

2.12. Formatando strings


Python formata valores em strings. Embora isso possa incluir expresses bastantes complicadas, o uso mais bsico inserir valores em uma string com usando %s. Formatao de strings em Python usa a mesma sintaxe que a funo sprintf em C.

Example 2.29. Apresentando formatao de strings


>>> k = "uid" >>> v = "sa" >>> "%s=%s" % (k, v) 'uid=sa'

A expresso toda retorna uma string. O primeiro %s substitudo pelo valor de k; o segundo %s substitudo pelo valor de v. Todos os demais caracteres da string (nesse caso, o sinal de igual) ficam como esto. Note que (k, v) uma tupla. Eu disse que elas serviam pra algo. Voc pode estar achando que isso trabalho demais para fazer uma simples concatenao de strings, e voc est certo, exceto que formatao de strings no apenas concatenao. Na verdade, no nem apenas formatao, tambm uma forma de coero de tipo.

Example 2.30. Formatao de strings versus concatenao


>>> uid = "sa" >>> pwd = "secret" >>> print pwd + " is not a good password for " + uid secret is not a good password for sa >>> print "%s is not a good password for %s" % (pwd, uid) secret is not a good password for sa >>> userCount = 6 >>> print "Users connected: %d" % (userCount, ) Users connected: 6 >>> print "Users connected: " + userCount Traceback (innermost last): File "<interactive input>", line 1, in ? TypeError: cannot add type "int" to string

+ o operador de concatenao de strings. Nesse caso trivial, a formatao de strings tem o mesmo resultado que uma concatenao. (userCount, ) uma tupla com um elemento. Sim, a sintaxe estranha, mas h uma boa razo para isso: , sem ambigidade, uma tupla. Na verdade, voc sempre pode incluir uma vrgula aps o ltimo elemento quando define uma lista, tupla ou dicionrio, mas a vrgula obrigatria em uma tupla com apenas um elemento. Se a vrgula no fosse obrigatria, o Python no saberia se (userCount) uma tupla com um elemento ou apenas o valor de userCount. Formatao de strings funciona com inteiros especificando %d ao invs de %s. Tentar concatenar uma string com uma no-string levanta uma exceo. Ao contrrio da formatao de strings, a concatenao s funciona quando tudo j for string.

Leitura recomendada

Python Library Reference sumariza todos os caracteres de formatao de strings. Effective AWK Programming discute todos os caracteres de formato e tcnicas avanadas de formatao de strings como a especificao de tamanho, preciso e complemento com zeros..

2.13. Mapeando listas


Um dos recursos mais poderosos de Python a compreenso de listas ("list comprehension"), que uma forma compacta de mapear uma lista com outra sem aplicar uma funo a cada elemento das lista.

Example 2.31. Apresentando compreenso de listas


>>> >>> [2, >>> [1, >>> >>> [2, li = [1, 9, 8, 4] [elem*2 for elem in li] 18, 16, 8] li 9, 8, 4] li = [elem*2 for elem in li] li 18, 16, 8]

Para entender o que isso significa, leia da direita para a esquerda. li a lista que voc est mapeando. Python itera pelos elementos de li um a um, temorariamente atribuindo o valor de outro elemento varivel elem. Python ento aplica a expresso elem*2 e adiciona o resultado lista retornada. Note que compreenses de lista no mudam a lista original. seguro atribuir o resultado da compreenso de lista varivel que voc est mapeando. No h race conditions FIXME ou qualquer esquisitisse com que se preocupar; a nova lista construda em memria, e quando a compreenso estiver completa, atribui o resultado varivel.

Example 2.32. Compreenses de lista em buildConnectionString


["%s=%s" % (k, v) for k, v in params.items()]

Primeiramente, note que estamos chamando a funo items do dicionrio params. Essa funo retorna uma lista de tuplas de todos os dados no dicionrio..

Example 2.33. keys, values e items


>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> params.keys() ['server', 'uid', 'database', 'pwd'] >>> params.values() ['mpilgrim', 'sa', 'master', 'secret'] >>> params.items() [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]

O mtodo keys de um dicionrio retorna uma lista de todas as chaves. A lista no est na ordem em que o dicionrio for definido (lembre-se, elementos em um dicionrio no tm ordem), mas uma lista. O mtodo values retorna uma lista de todos os valores. A lista est na mesma ordem que a lista retornada por keys, portanto params.values()[n] == params[params.keys() [n]] para todos os valores de n. O mtodo items retorna uma tupla no formato (chave, valor). A lista contm todos os dados no dicionrio. Agora vamos ver o que buildConnectionString faz. Ela toma uma lista, params.items (), e a mapeia a uma nova lista aplicanfo formatao de string a cada elemento. A nova lista tem o mesmo nmero de elementos que params.items(), mas cada elemento na nova lista ser uma string que contm tanto uma chave quanto seu valor associado no dicionrio params.

Example 2.34. Compreenso de listas em buildConnectionString, passo a passo


>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> params.items() [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')] >>> [k for k, v in params.items()] ['server', 'uid', 'database', 'pwd'] >>> [v for k, v in params.items()] ['mpilgrim', 'sa', 'master', 'secret'] >>> ["%s=%s" % (k, v) for k, v in params.items()] ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']

Note que estamos usando duas variveis para iterar pela lista params.items(). Esse mais um caso do uso de atribuio mltipla. O primeiro elemento de params.items() ('server', 'mpilgrim'), ento na primeira iterao da compreenso, k receber 'server' e v receber 'mpilgrim'. Nesse caso estamos ignorando o valor de v e incluindo apenas o valor de k na lista retornada, ento essa compreenso acaba sendo equivalente a params.keys(). (Voc no precisaria usar uma compreenso como essa em cdigo de produo. Esse um exemplo simples para aprendermos o que est acontecendo aqui.) Aqui fazemos a mesma coisa, ignorando o valor de k, portanto essa compreenso de lista acaba sendo equivalente a params.values(). Combinando os exemplos anteriores com alguma formatao de string, conseguimos uma lista de strings que inclui tanto a chave e quanto o valor de cada elemento do dicionrio. Isso se parece muito com a sada do programa; tudo que resta juntar os elementos dessa lista em uma nica string.

Leitura recomendada

Python Tutorial discute outra forma de mapear listas usando a funo interna map. Python Tutorial mostra fazer compreenses de listas dentro de compreenses de listas.

2.14. Unindo listas e separando strings


Voc tem uma lista de pares chave-valor no formato chave=valor e voc quer uni-los em uma nica string. Para juntar qualquer lista de strings, use o mtodo join do objeto string.

Example 2.35. Unindo a lista em buildConnectionString


return ";".join(["%s=%s" % (k, v) for k, v in params.items()])

Uma nota interessante antes de continuarmos. Eu repito o tempo todo que funes so objetos, strings so objetos, tudo um objeto. Voc pode ter entendido que as variveis que contm strings so objetos. Mas examine cuidadosamente o prximo exemplo e voc ver que a prpria string ";" um objeto, e voc estar chamando seu mtodo join. Continuando, o mtodo join une os elementos de uma lista em uma nica string, com cada elemento separado por ponto-e-vrgula. O delimitador no precisa ser um ponto-e-vrgula, e nem sequer precisa ser apenas um caracter. Qualquer string serve. join funciona apenas com listas de strings, e no faz nenhum outro tipo de coero. Tentar unir com join uma lista que tem um ou mais elementos no-string levanta uma exceo.

Example 2.36. Sada de odbchelper.py


>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> ["%s=%s" % (k, v) for k, v in params.items()] ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret'] >>> ";".join(["%s=%s" % (k, v) for k, v in params.items()]) 'server=mpilgrim;uid=sa;database=master;pwd=secret'

Essa string ento retornada da funo odbchelper e impressa pelo bloco que a chamou, que por sua vez imprime a sada que deixou voc maravilhado no incio desse captulo. Nota histrica. Quando aprendi Python, eu esperava que join fosse um mtodo de uma lista e que tomaria o delimitador como argumento. Muitas pessoas acham isso, mas h uma histria que justifica o mtodo join. Antes do Python 1.6, strings no tinham esses mtodos todos. Havia um mdulo string separado que continha todas as funes de strings, e todas essas funes tomavam uma string como primeiro argumento. Essas funes foram consideradas importantes o suficiente para serem colcadas dentro das prprias strings, o que fazia sentido para funes como lower, upper e split. Mas muitos fs tradicionais do Python se opuseram ao mtodo join, argumentando que ele deveria ser um mtodo das listas, ou pelo menos que no deveria sair do mdulo string (que ainda tem muita coisa til). Eu uso o novo mtodo join exclusivamente, mas voc pode ver cdigo escrito das duas formas, e caso essa forma o incomode, use a funao antiga string.join. Voc deve estar se pergutando se h uma forma anloga de dividir uma string em uma lista. E claro que h, e se chama split.

Example 2.37. Dividindo uma string


>>> li = ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret'] >>> s = ";".join(li) >>> s 'server=mpilgrim;uid=sa;database=master;pwd=secret'

>>> s.split(";") ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret'] >>> s.split(";", 1) ['server=mpilgrim', 'uid=sa;database=master;pwd=secret']

split reverte join, pois divide uma string em uma lista de vrios elementos. Note que o delimitador (;) foi removido totalmente, e no faz parte dos elementos da lista retornada. split aceita um segundo argumento opcional, a quantidade mxima de elementos da lista. ("Oh, argumentos opcionais... Voc vai aprender como fazer isso em suas prprias funes no prximo captulo.) qualquerstring.split(delimitador, 1) uma tcnica til quando voc quer procurar uma string em outra e ento trabalhar com tudo antes do texto encontrado (que fica no primeiro elemento da lista retornada) e tudo depois do texto encontrado (que fica depois do segundo elemento). FIXME rever estilo.

Leitura recomendada

Python Knowledge Base responde perguntas comuns sobre strings e tem muitos exemplos de cdigo usando strings. Python Library Reference sumariza todos os mtodos de strings. Python Library Reference documenta o mdulo string. The Whole Python FAQ explica porque join um mtodo de string e no um mtodo de lista.

2.15. Resumo
O programa odbchelper.py e sua sada fazem total sentido.

Example 2.38. odbchelper.py


def buildConnectionString(params): """Build a connection string from a dictionary of parameters. Returns string.""" return ";".join(["%s=%s" % (k, v) for k, v in params.items()]) if __name__ == "__main__": myParams = {"server":"mpilgrim", \ "database":"master", \ "uid":"sa", \ "pwd":"secret" \ } print buildConnectionString(myParams)

Example 2.39. Sada de odbchelper.py


server=mpilgrim;uid=sa;database=master;pwd=secret

Antes de mergulhar no prximo captulo, certifique-se de que voc faz confortavelmente as seguintes tarefas:

Usar o IDE Python para testar expresses interativamente

Escrever mdulos de forma que tambm possam ser usados como programas auto-suficientes, pelo menos para fins de teste Importar mdulos e chamar suas funes Declarar funes usando doc strings, variveis locais e indentao correta Definir dicionrios, tuplas e listas Acessar atributos e mtodos de qualquer objeto, inclusive strings, listas, dicionrios, funes e mdulos Concatenar valores com formatao de strings Mapear listas em outras listas usando compreenses de listas Dividir strings em listas e unir listas em strings

Chapter 3. O poder da introspeco


3.1. Mergulhando 3.2. Argumentos opcionais e nomeados 3.3. type, str, dir, e outras funes internas 3.4. Extraindo referncias a objetos com getattr 3.5. Filtrando listas 3.6. A natureza peculiar de and e or 3.7. Using lambda functions 3.8. Putting it all together 3.9. Summary

3.1. Mergulhando
O presente captulo cobre um dos pontos fortes do Python: introspeco. Como voc deve saber, tudo em Python um objeto. A introspeco a capacidade de fazer cdigo que examina e manipula mdulos e funes em memria como objetos. A partir daqui, definiremos funes sem nomes, chamaremos funes com argumentos fora de ordem e faremos referncia funes cujos nomes no conhecemos previamente. Aqui temos um programa Python completo e funcional. Voc deve entender boa parte dele. As linhas numeradas ilustram conceitos cobertos em Conhecendo o Python. No se preocupe se o resto parecer intimidador; voc vai aprender tudo isso no decorrer desse captulo.

Example 3.1. apihelper.py


If you have not already done so, you can download this and other examples used in this book.
def help(object, spacing=10, collapse=1): """Print methods and doc strings. Takes module, class, list, dictionary, or string.""" methodList = [method for method in dir(object) if callable(getattr(object, method))] processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList]) if __name__ == "__main__":

print help.__doc__

Este mdulo tem apenas uma funo, help. De acordo com sua declarao, ela aceita trs parmetros: objectv, spacing e collapse. Os dois ltimos so na verdade opcionais, como veremos em breve. A funo help tem uma doc string multi-linhas que sucintamente descreve seu propsito. Note que nenhum valor de retorno mencionado: esta funo ser usada apenas pelos seus efeitos, no por seu valor de retorno. O cdigo dentro da funo est indentado. O truque if __name__ permite que o programa faa algo til quando executado sozinho, sem impedir seu uso como um mdulo por outros programas. Nesse caso, o programa simplesmente imprime a doc string da funo help. Comandos if usam == para comparao, e parnteses no so obrigatrios. A funo help foi projetada para ser usada por voc, programador, enquanto trabaliha no Python IDE. Ela aceita qualquer objeto que tem funes ou mtodos (como um mdulo, que tem funes, ou uma lista, que tem mtodos) e imprime as funes e as doc strings.

Example 3.2. Exemplo de uso de apihelper.py


>>> from apihelper import help >>> li = [] >>> help(li) append L.append(object) -- append object to end count L.count(value) -> integer -- return number of occurrences of value extend L.extend(list) -- extend list by appending list elements index L.index(value) -> integer -- return index of first occurrence of value insert L.insert(index, object) -- insert object before index pop L.pop([index]) -> item -- remove and return item at index (default last) remove L.remove(value) -- remove first occurrence of value reverse L.reverse() -- reverse *IN PLACE* sort L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1

Por padro a sada formatada para ser legvel. doc strings multi-linhas so transformadas em uma linha longa. Esse comportamento pode ser alterado especificando 0 como valor do argumento collapse. Se os nomes de funo forem mais longos que 10 caracteres, voc pode especificar um valor maior para o parmetro spacing para deixar a sada mais fcil de ler.

Example 3.3. Uso avanado de apihelper.py


>>> import odbchelper >>> help(odbchelper) buildConnectionString Build a connection string from a dictionary Returns string. >>> help(odbchelper, 30) buildConnectionString Build a connection string from a dictionary Returns string. >>> help(odbchelper, 30, 0) buildConnectionString Build a connection string from a dictionary Returns string.

3.2. Argumentos opcionais e nomeados


Python suporta valores padro para argumentos de funes. Se a funo for chamada sem o argumento, o valor padro usado. Alm disso, argumentos podem ser especificados em qualquer ordem usando argumentos nomeados. Procedimentos embutidos em Transact/SQL podem fazer isso tambm. Se voc conhecer SQL Server pode passar rapidamente por essa parte.

Example 3.4. help, uma funo com dois argumentos opcionais


def help(object, spacing=10, collapse=1):

spacing e collapse so opcionais, uma vez que seus valores padro esto definidos. object obrigatrio, pois nenhum valor padro foi definido. Se help for chamado com apenas um argumento, spacing ser 10 e collapse ser 1. Se help for chamado com dois argumentos, collapse ser por padro 1. Suponha que voc queira especificar o valor de collapse mas queira aceitar o valor padro de spacing. Na maioria das outras linguagens isso no possvel pois seria obrigatrio passar trs parmetros. Mas em Python argumentos podem ser especificados pelo nome, em qualquer ordem.

Example 3.5. Chamadas vlidas de help


help(odbchelper) help(odbchelper, 12) help(odbchelper, collapse=0) help(spacing=15, object=odbchelper)

Com apenas um argumento, spacing fica com o valor padro 10 e collapse fica com o valor padro 1. Com dois argumentos, collapse fica com o valor padro 1. Aqui voc est nomeando o argumento collapse explicitamente e especificando seu valor. spacing continua com o valor padro 10. Mesmo argumentos obrigatrios (como object, que no tem um valor padro) podem ser nomeados, e os argumentos nomeados podem aparecer em qualquer ordem. Isso parece particularmente estranho at voc perceber que os argumentos so simplesmente um dicionrio. O mtodo normal de chamar funes sem nomes de argumentos apenas um atalho em que o Python associa os valores com os argumentos na ordem que voc especificou na declarao. E na maior parte do tempo, as funes sero chamadas do jeito normal, e a flexibilidade adicional estar l quando voc precisar. A nica coisa que voc ecisa fazer para chamar uma funo especificar um valor (de qualquer forma) para cada argumento obrigatrio. A maneira e a ordem voc que escolhe.

Leitura adicional

Python Tutorial discute quando exatamente e como argumentos padro so avaliados, o que importa quando o valor padro for uma lista ou uma expresso com efeitos colaterais ("side effects").

3.3. type, str, dir, e outras funes internas


Python tem um pequeno conjunto de funes extremamente teis. Todas as outras funes so particionadas em mdulos. Isso foi uma deciso de projeto consciente, de forma a manter o ncleo linguagem livre dos excessos de outras linguagens de script (cof cof, Visual Basic). A funo type retorna o tipo de um objeto arbitrrio. Os tipos possveis so listados no mdulo types. Esse recurso til em funes auxiliares que podem manipular diversos tipos de dados.

Example 3.6. Introduzindo type


>>> type(1) <type 'int'> >>> li = [] >>> type(li) <type 'list'> >>> import odbchelper >>> type(odbchelper) <type 'module'> >>> import types >>> type(odbchelper) == types.ModuleType 1

type recebe qualquer coisa como valor e retorna o tipo. E eu realmente quis dizer qualquer coisa: inteiros, stri funes, classes, mdulos, at mesmo tipos. type recebe uma varivel e retorna seu tipo. type tambm funciona com mdulos. possvel usar as constantes no mdulo types para comparar tipos de objetos. isso que a funo help faz, str pega dados e retorna como string. Todos os tipos podem ser transformados em string.

Example 3.7. Introduzindo str


>>> str(1) '1' >>> horsemen = ['war', 'pestilence', 'famine'] >>> horsemen.append('Powerbuilder') >>> str(horsemen) "['war', 'pestilence', 'famine', 'Powerbuilder']" >>> str(odbchelper) "<module 'odbchelper' from 'c:\\docbook\\dip\\py\\odbchelper.py'>" >>> str(None) 'None'

Para tipos de dados simples como inteiros, seria normal esperar que str funcionaria, pois virtualmente todas as converter inteiros em strings. str, porm, funciona com qualquer tipo. Aqui funciona com uma lista que construimos em pedaos. str tambm funciona com mdulos. Note que a representao como string de um mdulo inclui o caminho do resultado ser diferente. Um comportamento sutil mas importante de str o fato de funcionar com None, o valor nulo de Python. O re usar isso a nosso favor na funo help como veremos em breve. No corao de nossa funo help est a poderosa funo dir. dir retorna uma lista dos atributos e mtodos de qualquer objeto: mdulos, funes, listas, strings, dicionrios... virtualmente tudo.

Example 3.8. Introduzindo dir


>>> li = [] >>> dir(li) ['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>> d = {} >>> dir(d) ['clear', 'copy', 'get', 'has_key', 'items', 'keys', 'setdefault', 'update', 'values'] >>> import odbchelper >>> dir(odbchelper) ['__builtins__', '__doc__', '__file__', '__name__', 'buildConnectionString']

li uma lista, portanto dir(li) retorna uma lista de todos os mtodos da lista. Note que a lista retornada co strings, no os prprios mtodos. d um dicionrio, portanto dir(d) retorna uma lista de todos os nomes dos mtodos de dicionrios. Pelo men familiar. aqui que as coisas ficam interessantes. odbchelper um mdulo, portanto dir(odbchelper) retorna definido nesse mdulo, inclusive atributos internos como __name__ e __doc__, e quaisquer outros atributos caso, odbchelper tem apenas um mtodo definido pelo usurio, a funo buildConnectionString qu Python. Finalmente, a funo callable recebe como parmetro um objeto e retorna 1 se o objeto puder ser chamado ou 0 caso contrrio. Objetos chamveis incluem funes, mtodos de classes e at mesmo as prprias classes. (Mais sobre classes no captulo 3.)

Example 3.9. Introduzindo callable


>>> import string >>> string.punctuation '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' >>> string.join <function join at 00C55A7C> >>> callable(string.punctuation) 0 >>> callable(string.join) 1 >>> print string.join.__doc__ join(list [,sep]) -> string Return a string composed of the words in list, with intervening occurrences of sep. The default separator is a single space. (joinfields and join are synonymous)

As funes no mdulo string so obsoletas (embora muita gente ainda use a funo join), mas o mdulo co string.punctuation, que contm todos os caracteres de pontuao. string.join uma funo que une uma lista de strings. string.punctuation no chamvel FIXME, e sim uma string. (Uma string tem objetos chamveis, mas string.join chamvel; uma funo que aceita dois argumentos. Qualquer objeto chamvel pode ter uma doc string. Usando a funo callable em cada um dos atributo com quais atributos nos importamos (mtodos, funes, classes) e quais queremos ignorar (contantes, etc.) sem previamente. type, str, dir e todas as outras funes internas do Python esto agrupadas no mdulo

__builtin__. (O nome tem dois sublinhados no comeo e dois no fim.) Se ajudar, pense que Python automaticamente executa from __builtin__ import * ao iniciar, o que importa todas as funes desse mdulo no escopo atual para que possam ser usadas diretamente. A vantagem de pensar dessa forma que possvel acessar todas as funes e atributos internos examinando o mdulo __builtin__. E adivinhe s, ns temos uma funo para fazer isso: ela se chama help. Tente fazer isso e examine a lista agora; ns mergulharemos em algumas das funes mais importantes mais tarde. (algumas das classes de erro internas, como AttributeError, devem ser familiares.)

Example 3.10. Funes e atributos internos


>>> from apihelper import help >>> import __builtin__ >>> help(__builtin__, 20) ArithmeticError Base class for arithmetic errors. AssertionError Assertion failed. AttributeError Attribute not found. EOFError Read beyond end of file. EnvironmentError Base class for I/O related errors. Exception Common base class for all exceptions. FloatingPointError Floating point operation failed. IOError I/O operation failed. [...corte...]

Python vem com manuais de referncia excelentes, que voc deve usar largamente para conhecer todos os m enquanto em outras linguagens voc ficaria voltando o tempo todo aos manuais (ou man pages, ou, Deus te li us-los, Python na maior parte auto-documentado.

Leitura recomendada

Python Library Reference documenta todas as funes internas e todas as excees internas.

3.4. Extraindo referncias a objetos com getattr


Voc j sabe que funes so objetos. O que voc no sabe ainda que possvel fazer referncia a uma funo sem saber seu nome at o tempo de execuo, usando a funo getattr.

Example 3.11. Apresentando getattr


>>> li = ["Larry", "Curly"] >>> li.pop <built-in method pop of list object at 010DF884> >>> getattr(li, "pop") <built-in method pop of list object at 010DF884> >>> getattr(li, "append")("Moe") >>> li ["Larry", "Curly", "Moe"] >>> getattr({}, "clear") <built-in method clear of dictionary object at 00F113D4> >>> getattr((), "pop") Traceback (innermost last):

File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'pop'

Aqui temos uma referncia ao mtodo pop da lista. Note que no estamos chamando o mtodo pop, que seria feito com li.pop()). uma referncia ao prprio mtodo. Isso tambm retorna uma referncia ao mtodo pop, mas dessa vez, o nome do mtodo especificado como argumento da funo getattr. getattr uma funo interna muito til que retorna qualquer atributo de qualquer objeto. Nesse caso, o objeto uma lista, e o atributo o mtodo pop Caso voc no tenha percebido como isso til, tente isso: o valor de retorno de getattr o mtodo, que voc pode ento chamar como se tivesse usado li.append("Moe") diretamente. Mas voc no chamou a funo diretamente: voc especificou o nome da funo como uma string. getattr tambm funciona com dicionrios. Em tese, getattr deveria funcionar com tuplas, exceto que tuplas no tm mtodos, portanto getattr levanta uma exceo no importa que nome de atributo voc use. getattr no apenas para tipos embutidos. Tambm funciona com mdulos.

Example 3.12. getattr in apihelper.py


>>> import odbchelper >>> odbchelper.buildConnectionString <function buildConnectionString at 00D18DD4> >>> getattr(odbchelper, "buildConnectionString") <function buildConnectionString at 00D18DD4> >>> object = odbchelper >>> method = "buildConnectionString" >>> getattr(object, method) <function buildConnectionString at 00D18DD4> >>> type(getattr(object, method)) <type 'function'> >>> import types >>> type(getattr(object, method)) == types.FunctionType 1 >>> callable(getattr(object, method)) 1

Isso retorna uma referncia funo buildConnectionString do mdulo odbchelper que estudamos em Conhecendo o Python. (O endereo hexadecimal especfico da minha mquina. O seu ser diferente.) Usando getattr, podemos pegar uma referncia mesma funo. Geralmente, getattr (objeto, "atributo") equivalente a objeto.atributo. Se objeto for um mdulo, atributo pode ser qualquer coisa definida no mdulo: uma funo, classe ou varivel global. E isso que usamos na funo help. object passado para a funo como um argumento, e method uma string que o nome de um mtodo ou de uma funo. Nesse caso, method o nome de uma funo, o que podemos provar verificando seu tipo. Como method uma funo, chamvel.

3.5. Filtrando listas


Como voc sabe, Python tem recursos poderosos para mapear listas em outras listas usando compreenses. Isso pode ser combinado com um mecanismo de filtragem, em que alguns elementos da lista so mapeados e outros so ignorados.

Example 3.13. Sintaxe para filtragem de listas


[expresso-de-mapeamento for elemento in lista-de-origem if expresso-defiltragem]

Isso uma extenso das compreenses de lista que voc conhece e confia. As primeiras duas partes so iguais; a ltima parte, iniciada no if, a expresso de filtragem. Uma expresso de filtragem pode ser qualquer expresso que avalie em verdadeiro ou falso (quem em Python pode ser quase qualquer coisa). Qualquer elemento para o qual a expresso de filtragem verdadeira ser includo no mapeamento. Todos os demais sero ignorados, no sendo passados para a expresso de mapeamento e ficando fora da lista de sada.

Example 3.14. Introduzindo filtragem de listas


>>> li = ["a", "mpilgrim", "foo", "b", "c", "b", "d", "d"] >>> [elem for elem in li if len(elem) > 1] ['mpilgrim', 'foo'] >>> [elem for elem in li if elem != "b"] ['a', 'mpilgrim', 'foo', 'c', 'd', 'd'] >>> [elem for elem in li if li.count(elem) == 1] ['a', 'mpilgrim', 'foo', 'c']

A expresso de mapeamento aqui simples (apenas retorna o valor de cada elemento), portanto se concentre na expresso de filtragem. medida em que o Python itera pelos elementos da lista, passa cada elemento por uma expresso de filtragem. Se a expresso de filtragem for verdadeira, o elemento mapeado e o resultado da expresso de mapeamento includo na lista retornada. Aqui estamos filtrando fora todas as strings de um caracter, de forma que s sobram uma lista com as strings mais longas. Aqui estamos filtrando fora um valor especfico, b. Note que isso filtra todas as ocorrncias de b, uma vez que cada vez que ele aparece, a expresso se torna verdadeira. count um mtodo de lista que retorna o nmero de vezes que um valor ocorre em uma lista. Voc pode pensar que esse filtro eliminaria as duplicatas da lista, retornando uma lista contendo apenas uma cpia de cada valor da lista original. Mas no o caso, porque valores que aparecem duas vezes na lista original (nesse caso, b e d) so excludos completamente. H formas de eliminar valores duplicados em uma lista, mas no com filtragem.

Example 3.15. Filtrando uma lista em apihelper.py


methodList = [method for method in dir(object) if callable(getattr(object, method))]

Isso parece complicado, e complicado, mas a estrutura bsica a mesma. A expresso de filtragem toda retorna uma lista, que atribuda varivel methodList. A primeira metade da expresso o mapeamento de lista. A expresso de mapeamento uma expresso identidade: retorna o valor de cada elemento. dir(object) retorna uma lista dos mtodos e atributos de object; essa a lista

que estamos mapeando. Portanto a nica parte nova a expresso de filtragem aps o if. A expresso de filtragem parece assustadora, mas no . Voc j aprendeu sobre callable, getattr e in. Como vimos na seo anterior, a expresso getattr(object, method) retorna um objeto funo se object for um mdulo e method o nome de uma funo do mdulo. Portanto essa expresso aceita um objeto (chamado object). Ento pega uma lista dos nomes dos atributos do objeto, mtodos, funes e algumas coisas mais. Ento filtra a lista para remover tudo que no nos importa. Fazemos isso tomando o nome de cada atributo/mtodo/funo e pegando uma referncia ao objeto real equivalente com o uso de getattr. Ento verificamos se o objeto chamvel, o que inclui quaisquer mtodos e funes, sejam embutidos (como o mtodo pop em uma lista) ou definidos pelo usurio (como a funo buildConnectionString do mdulo odbchelper). No nos importamos com outros atributos, como __name__, que faz parte de todos os mdulos.

Leitura recomendada

Python Tutorial discute outra forma de filtrar listas usando a funo embutida filter.

3.6. A natureza peculiar de and e or


Em Python, and e or realizam lgica booleana da maneira como voc esperaria, mas no retornam valores booleanos: eles retornam um dos valores que esto comparando.

Example 3.16. Apresentando and


>>> 'a' and 'b' 'b' >>> '' and 'b' '' >>> 'a' and 'b' and 'c' 'c'

Quando usamos and, os valores so avaliados em um contexo booleano da esquerda para a direita. 0, '', [], (), {} e None so falsos em um contexo booleano; tudo mais verdadeiro.[5] Se todos os valores forem verdadeiros em um contexto booleano, and retorna o ltimo valor. Nesse caso, and avalia 'a', que verdadeiro, ento 'b', que verdadeiro, e retorna 'b'. Se qualquer valor for falso em um contexto booleano, and retorna o primeiro valor falso. Nesse caso '' o primeiro valor falso.. Todos os valores so verdadeiros, portanto and retorna o ltimo valor, 'c'.

Example 3.17. Apresentando or


>>> 'a' >>> 'b' >>> {} >>> ... 'a' or 'b' '' or 'b' '' or [] or {} def sidefx(): print "in sidefx()"

... return 1 >>> 'a' or sidefx() 'a'

Quando usamos or, valores so avaliados em um contexto booleando da esquerda para a direita, como com and. Se algum valor for verdadeiro, or retorna esse valor imediatamente. Nesse caso, 'a' o primeiro valor verdadeiro. or avalia '', que falso, ento 'b', que verdadeiro, e retorna 'b'. Se todos os valores forem falsos, or retorna o ltimo valor. or avalia '', que falso, ento [], que falso, ento {}, wque falso, e retorna {}. Note que or avalia valores apenas at achar algum que seja verdadeiro em um contexto booleano, e ignora o resto. Essa distino importante se alguns valores tm efeitos colaterais. Aqui, a funo sidefx nunca chamada, porque or avalia 'a', que verdadeiro, e retorna 'a' imediatamente. Se voc for um programador C, certamente conhece a expresso bool ? a : b, que avalia em a se bool for verdadeiro, e b caso contrrio. Graas forma como and e or funcionam em Python, voc pode fazer a mesma coisa.

Example 3.18. Apresentando o truque and-or


>>> a = "first" >>> b = "second" >>> 1 and a or b 'first' >>> 0 and a or b 'second'

This syntax looks similar to the bool ? a : b expression in C. The entire expression is evaluated from left to right, so the and is evaluated first. 1 and 'first' evalutes to 'first', then 'first' or 'second' evalutes to 'first'. 0 and 'first' evalutes to 0, then 0 or 'second' evaluates to 'second'. However, since this Python expression is simply boolean logic, and not a special construct of the language, there is one very, very, very important difference between this and-or trick in Python and the bool ? a : b syntax in C. If the value of a is false, the expression will not work as you would expect it to. (Can you tell I was bitten by this? More than once?)

Example 3.19. When the and-or trick fails


>>> a = "" >>> b = "second" >>> 1 and a or b 'second'

Since a is an empty string, which Python considers false in a boolean context, 1 and '' evalutes to '', then '' or 'second' evalutes to 'second'. Oops! That's not what we wanted. The and-or trick, bool and a or b, will not work like the C expression bool ? a : b when a is false in a boolean context. The real trick behind the and-or trick, then, is to make sure that the value of a is never false. One common way of doing this is to turn a into [a] and b into [b], then taking the first element of the returned list, which will be either a or b.

Example 3.20. Using the and-or trick safely


>>> a = "" >>> b = "second" >>> (1 and [a] or [b])[0] ''

Since [a] is a non-empty list, it is never false. Even if a is 0 or '' or some other false value, the list [a] is true because it has one element. By now, this trick may seem like more trouble than it's worth. You could, after all, accomplish the same thing with an if statement, so why go through all this fuss? Well, in many cases, you are choosing between two constant values, so you can use the simpler syntax and not worry, because you know that the a value will always be true. And even if you have to use the more complicated safe form, there are good reasons to do so; there are some cases in Python where if statements are not allowed, like lambda functions.

Further reading

Python Cookbook discusses alternatives to the and-or trick.

Footnotes
[5] bem,

quase tudo. Por padro, instncias de classes so verdadeiras em um contexto booleano, mas possvel definir mtodos especiais em sua classe para fazer com que avaliem falso. Vamos aprender tudo sobre classes e mtodos especiais no captulo 3.

Você também pode gostar