O básico - DocShare.tips

Propaganda
Este é um curso intensivo mínimo para a linguagem de programação Python. Para aprender mais, veja a
documentação no site www.python.org; especialmente o tutorial. Se você está se perguntando porque
deveria se interessar, veja esta comparação entre o Python e outras linguagens.
Esta introdução tem recebido elogios de leitores satisfeitos, e está sendo traduzida para vários idiomas,
entre os quais russo, norueguês, português (esta página!) e espanhol. A versão original, em inglês,
está aqui.
O básico
Para começar, pense em Python como sendo pseudo-código. Isto é quase uma verdade. Variáveis não
têm tipos, assim você não precisa declará-las. Elas são criadas quando você lhes atribui um valor, e são
destruídas quando não forem mais usadas. A atribuição é feita pelo operador =. A igualdade é testada
com o operador ==. Você pode atribuir mais de uma variável ao mesmo tempo:
Esconder número das linhas
1 x , y , z = 1, 2, 3

primeiro, segundo, terceiro = primeiro, segundo, terceiro
ou um, dois, tres = 1, 2, 3
Esconder número das linhas
1 a = b = 123
Os blocos são indicados somente pela indentação (nada de BEGIN/END ou chaves). Algumas estruturas
de controle são:
Esconder número das linhas
1
2
3
4
5
6
7
8
9
10
i f x < 5 or ( x > 10 and x < 20) :
pr i nt " O v al or es t á c or r et o. "
i f x < 5 or 10 < x < 20:
pr i nt " O v al or es t á c or r et o. "
f or i i n [ 1, 2, 3, 4, 5] :
pr i nt " Es t a é a i t er aç ão númer o" , i
x = 10
whi l e x >= 0:
pr i nt " x ai nda não é negat i v o. "
x = x - 1
Os primeiros dois exemplos são equivalentes.
A variável de índice no laço for varia de acordo com os elementos de uma lista (escrita como no
exemplo). Para fazer um laço for comum (isto é, um laço de contagem), use a função embutida range().
Esconder número das linhas
1 # Mos t r a os v al or es de 0 a 99 i nc l us i v e.
2 f or v al or i n r ange( 100) :
3
pr i nt v al or
(A linha começando por "#" é um comentário, sendo ignorada pelo interpretador.)
Vejamos: agora você já sabe o suficiente (em teoria) para implementar qualquer algoritmo em Python.
Vamos incluir alguma interação básica com o usuário. Para obter dados do usuário (a partir de
um prompt texto), use a função embutida input().
Esconder número das linhas
1 x = i nput ( " Por f av or di gi t e um númer o: " )
2 pr i nt " O quadr ado des s e númer o é" , x * x
A função input() mostra o texto dado (o qual pode ser vazio) e deixa o usuário entrar qualquer valor
válido em Python. Neste caso nós estamos esperando um número - se alguma outra coisa (como uma
string) for fornecida, o programa poderá falhar. Para evitar isto nós devemos implementar alguma
checagem de erro. Eu não vou entrar em detalhes aqui; é suficiente dizer que se você deseja receber o
dado do usuário, literalmente como uma string (assim qualquer coisa pode ser fornecida), use a
função raw_input(). Se você deseja converter uma string s para um inteiro, você poderia
usar int(s).
Nota: Se o usuário deseja fornecer uma string com input(), ele deverá escrever as aspas
explicitamente. Em Python, as stringspodem ser delimitadas com aspas simples ou duplas.
Assim, já que temos estruturas de controle, entrada e saída - agora nós precisamos de algumas
estruturas de dados. As mais importantes são as listas e os dicionários. As listas são escritas com
colchetes, e podem ser (naturalmente) aninhadas:
Esconder número das linhas
1 nome = [ " Cl ees e" , " J ohn" ]
2 x = [ [ 1, 2, 3] , [ y , z ] , [ [ [ ] ] ] ]
Uma das coisas mais interessantes sobre as listas é que os seus elementos podem ser acessados
separadamente ou em grupos, através de indexação e corte em fatias. A indexação é feita (como em
muitas outras linguagens) pela colocação do índice entre os colchetes (Note que o primeiro elemento tem
índice 0).
Esconder número das linhas
1 pr i nt nome[ 1] , nome[ 0] # Mos t r a " J ohn Cl ees e"
2 nome[ 0] = " Smi t h"
O corte em fatias é parecido com a indexação, indicando-se os índices inicial e final separados por dois
pontos (":")
Esconder número das linhas
1 x = [ " s pam" , " s pam" , " s pam" , " s pam" , " s pam" , " eggs " , " and" , " s pam" ]
2 pr i nt x [ 5: 7] # Mos t r a a l i s t a [ " eggs " , " and" ]
Observe que o índice final não se inclui no resultado. Se um dos índices é omitido, assume-se que você
deseja todos os elementos na direção correspondente. Por exemplo, lista[:3] significa "cada
elemento desde o início da lista até o elemento 3, este não incluído." (Poderia-se dizer na verdade que vai
até o elemento 4, desde que a contagem inicia do 0... Oh, tudo bem) list[3:] significaria, por outro
lado, "cada elemento da lista, começando do elemento 3 (inclusive) até o último inclusive." Para outros
resultados bem interessantes, você pode usar números negativos também: list[-3] é o terceiro
elemento desde o final da lista...
Já que estamos falando de indexação, é interessante saber que a função embutida len() fornece o
tamanho de uma lista (em número de elementos).
E agora, o que há sobre os dicionários? Para ser breve, eles são como listas, mas o seu conteúdo não
está ordenado. Como você os indexa então? Bem, cada elemento tem uma chave, ou um "nome" que é
usado para buscar o elemento tal qual um dicionário de verdade. Eis dois dicionários como exemplo:
Esconder número das linhas
1 { " Al i c e" :
2
" Cl ar i c e"
3 pes s oa = { '
4
'
23452532, " Bor i s " : 252336,
: 2352525, " Dor i s " : 23624643}
nome' : " Robi n" , ' s obr enome' : " Hood" ,
oc upaç ão' : " Ladr ão" }
Agora, para obter a ocupação da pessoa, nós usamos a expressãopessoa["ocupação"]. Se nós
desejarmos alterar o seu sobrenome, nos poderíamos escrever:
Esconder número das linhas
1 pes s oa[ ' s obr enome' ] = " de Loc k s l ey "
Simples, não? Como as listas, os dicionários podem armazenar outros dicionários. Ou listas, que já
conhecemos. E naturalmente listas podem armazenar dicionários também. Desta forma, você pode
conseguir estruturas de dados bastante avançadas.
Funções
Próximo passo: Abstração. Queremos dar um nome a um pedaço de código, e chamá-lo com um
parâmetro. Em outras palavras - nós queremos definir uma função (ou "procedimento"). Isto é fácil. Use a
palavra-chave def assim:
Esconder número das linhas
1 def quadr ado( x ) :
2
r et ur n x * x
3 pr i nt quadr ado( 2) # Mos t r a 4
Para os que podem entender: Quando você passa um parâmetro à uma função, você vincula o parâmetro
ao valor (passado), criando, portanto, uma nova referência. Se você mudar o "conteúdo" deste parâmetro
não afetará o original. Funciona como em Java, por exemplo. Vamos dar uma olhada em um exemplo:
Esconder número das linhas
1
2
3
4
5
def mudar ( l i s t a_qual quer ) :
l i s t a_qual quer [ 1] = 4
x = [ 1, 2, 3]
mudar ( x )
pr i nt x # Mos t r a [ 1, 4, 3]
Como você pode ver, a lista original é que foi passada, e se a função mudá-la, essas mudanças serão
refletidas para o local de onde a função foi chamada. Note, entretanto, o comportamento no seguinte
exemplo:
Esconder número das linhas
1
2
3
4
5
def naoMudar ( x ) :
x = 0
y = 1
naoMudar ( y )
pr i nt y # Mos t r a 1
Por que não há mudança agora? Porque nós não mudamos o valor! O valor passado é o número 1 -- nós
não podemos mudar um número do mesmo modo que mudamos uma lista. O número 1 é (e sempre será)
o número 1. O que nós realmente fizemos foi mudar o conteúdo da variável local (parâmetro x), e isto não
afetará o ambiente (fora da função).
Para os que não entenderam: Não se preocupem com isso
Python tem muitas coisas "legais" como argumentos com nome e argumentos com valor padrão, podendo
manipular um número variável de argumentos para uma função. Para mais informações sobre isto, veja
a seção 4.7 do tutorial de Python.
Se você sabe como usar funções em geral, isto é basicamente o que você precisa saber sobre elas em
Python. (Ah, sim... A palavra-chave return termina a execução da função e retorna o valor dado.)
Uma coisa que é útil saber, entretanto, é que as função são valores em Python. Assim se você tem uma
função como quadrado, você pode fazer alguma coisa assim:
Esconder número das linhas
1 f i gur a = quadr ado
2 f i gur a( 2) # Mos t r a 4
Para chamar uma função sem argumentos você deve lembrar de escrever func() e não func. A
segunda forma, como mostrado, somente retorna a própria função, como um valor. (Isto ocorre com os
métodos dos objetos também... Veja abaixo.)
Objetos e coisas...
Eu suponho que você saiba como funciona a programação orientada a objetos. (De outra forma, esta
seção não faria muito sentido. Sem problemas... Comece a brincar sem os objetos :).) Em Python você
define classes com a palavra-chave (surpresa!) class, assim:
Esconder número das linhas
1 c l as s Ces t a:
2
# Lembr e- s e s empr e do ar gument o * s el f *
3
def __i ni t __( s el f , c ont eudo=None) :
4
s el f . c ont eudo = c ont eudo or [ ]
5
def adi c i one( s el f , el ement o) :
6
s el f . c ont eudo. append( el ement o)
7
def mos t r e_me( s el f ) :
8
9
10
11
r es ul t = " "
f or el ement o i n s el f . c ont eudo:
r es ul t ado = r es ul t ado + " " + ` el ement o`
pr i nt " Cont ém: " +r es ul t ado
Coisas novas aqui:
1.
Todos os métodos (funções dentro de um objeto) recebem um argumento adicional no início da
lista de argumentos, contendo o próprio objeto. (Chamado self neste exemplo, por convenção.)
2. Métodos são chamados assim:objeto.método(arg1, arg2).
3. Alguns nomes de métodos, como __init__ são pré-definidos, e têm significado
especial. __init__ é o nome do construtor da classe, isto é, esta é a função que é
chamada quando você cria uma instância.
4.
Alguns argumentos podem ser opcionais e ter um valor padrão (como mencionado acima, na
seção sobre funções). Isto é feito escrevendo-se a definição desta forma:
Esconder número das linhas
1 def s pam( i dade=32) : # . . .
 Aqui, spam pode ser chamado com um ou zero parâmetros. Se nenhum for usado, então o
parâmetro idade terá o valor 32.

"Lógica de curto-circuito." Este é um ponto... Veja abaixo.
 Aspas simples invertidas convertem um objeto para sua representação como string. (Assim se
elemento contém o número 1, então elemento é o mesmo que "1" sendo 'elemento' uma
string literal.)

O sinal de adição + é usado também para concatenação de listas, e strings são na verdade listas
de caracteres (o que significa que você pode usar indexação e corte em fatias e a função len
com strings. Legal, não acha?)
Nenhum método ou variável membro é protegido (nem privado, nem nada parecido) em Python.
Encapsulação é na maioria das vezes um estilo de programação. (Se você realmente precisar, existem
convenções para nomes de variáveis, que permitem alguma privacidade :)).
E agora, sobre a lógica de curto-circuito...
Todos os valores em Python podem ser usados como valores lógicos. Alguns dos mais "vazios", tais
como [], 0, "" e None representam o valor lógico "falso", enquanto o resto dos valores (como [0], 1 ou "Olá
Mundo" representam o valor lógico "verdadeiro".
Assim, expressões lógicas como a and b são avaliadas deste modo: Primeiro, verifique se a é
verdadeiro. Se não, então simplesmente retorne-o. Se sim, então simplesmente retorne b (o que irá
representar o valor lógico da expressão.). A lógica correspondente para a or b é: se a é verdadeiro,
então retorne-o, Se não é, então retorne b.
Este mecanismo faz com que and e or se comportem como os operadores booleanos que
implementam, mas eles também permitem escrever expressões condicionais muito curiosas. Por
exemplo, o código
Esconder número das linhas
1 i f a:
2
pr i nt a
3 el s e:
4
pr i nt b
Poderia ser substituído por:
Esconder número das linhas
1 pr i nt a or b
Na verdade, isto já é alguma coisa do idioma Python, assim é melhor você ir se acostumando. Isto é o
que foi feito no métodoCesta.__init__. O argumento conteudo tem um valor padrão None(o que é,
entre outras coisas, falso). Portanto, para verificar se ele tem um valor, nós poderíamos escrever:
Esconder número das linhas
1 i f c ont eudo:
2
s el f . c ont eudo = c ont eudo
3 el s e:
4
s el f . c ont eudo = [ ]
É claro, agora você sabe como fazer de uma forma melhor. E por que nós não demos o valor padrão [] no
começo? Porque da maneira como o Python funciona, isto daria a todas as Cestas a mesma lista vazia
como valor padrão. Tão logo uma das listas começasse a ser preenchida, todas as outras teriam os
mesmo elementos, e o padrão não seria mais vazio... Para aprender mais sobre isto você deveria ler a
documentação e procurar a diferença entre identidade e igualdade.
Outra forma de fazer o anterior é:
Esconder número das linhas
1 def __i ni t __( s el f , c ont eudo=[ ] ) :
2
s el f . c ont eudo = c ont eudo[ : ]
Você pode adivinhar como isto funciona? Ao invés de usar a mesma lista vazia para todos, nós usamos a
expressão conteudo[:] para fazer uma cópia (Usamos uma fatia que contém a lista toda.)
Assim, para fazer uma Cesta e usá-la (isto é. para chamar alguns dos seus métodos) nós devemos fazer
algo assim:
Esconder número das linhas
1 b = Ces t a( [ ' maç ã' , ' l ar anj a' ] )
2 b. adi c i one( " l i mão" )
3 b. mos t r e_me( )
Há outros métodos mágicos além do __init__. Um desses métodos é __str__ que define como o
objeto será conhecido quando for tratado como uma string. Nós poderíamos usar este método ao invés
de mostre_me():
Esconder número das linhas
1 def __s t r __( s el f ) :
2
r es ul t = " "
3
f or el ement o i n s el f . c ont eudo:
4
5
r es ul t ado = r es ul t ado + " " + s t r ( el ement o)
r et ur n " Cont ém: " +r es ul t ado
Agora, se nós desejamos mostrar a cesta b, nós usaríamos simplesmente:
Esconder número das linhas
1 pr i nt b
Legal, não acha?
Subclasses são feitas assim:
Esconder número das linhas
1 c l as s Ces t aSpam( Ces t a) :
2
# ...
Python permite herança múltipla, assim você pode ter várias superclasses entre parênteses, separadas
por vírgulas. Classes são instanciadas assim: x = Cesta(). Construtores são implementados, como
disse, com a definição de uma função membro especial__init__. Digamos que CestaSpam tem um
construtor__init__(self,tipo).
assim: y = CestaSpam("maças").
Então
você
poderia
fazer
uma
cesta
spam
Se você, no construtor de CestaSpam precisar chamar o construtor de uma ou mais superclasses, você
poderia chamá-los desta forma:Cesta.__init__(self). Note que além dos parâmetros comuns,
você deve fornecer explicitamente o self, já que a superclasse__init__ não sabe qual instância está
tratando.
Para saber mais sobre as maravilhas da programação orientada a objeto em Python, veja seção 9 do
tutorial de Python.
Um truque mental de Jedi
(Esta seção está aqui porque eu acho que ela é muito interessante. Definitivamente esta seção não é
necessária para começar a aprender Python.)
Você gosta de exercícios mentais? Então, se você é realmente ousado, você gostará de ver o ensaio
do GuidoVanRossum sobre metaclasses. Se, entretanto, você prefere não explodir sua mente, irá
igualmente satisfazer-se com este pequeno truque.
Python usa espaços de nomes dinâmicos (não léxicos). Isto quer dizer que se há uma função como esta:
Esconder número das linhas
1 def s uc o_l ar anj a( ) :
2
r et ur n x * 2
... onde uma variável (neste caso x) não está ligada a um argumento e não é dado um valor dentro da
função, Python usará o valor que ela tiver onde e quando a função for chamada. Neste caso:
Esconder número das linhas
1 x = 3
2
3
4
5
6
y =
# y
x =1
y =
# y
s uc o_l ar anj a( )
agor a é 6
s uc o_l ar anj a( )
agor a é 2
Normalmente este é o tipo de comportamento esperado (apesar do exemplo ser um pouco rebuscado raramente acessamos variáveis desta forma.) Entretanto, algumas vezes pode ser útil ter um espaço de
nomes estático, ou seja, armazenar alguns valores do ambiente em que a função é criada. A maneira de
fazer isto em Python é por meio dos argumentos padrão.
Esconder número das linhas
1 x = 4
2 def s uc o_mac a( x =x ) :
3
r et ur n x * 2
Aqui, ao argumento x é atribuído o valor padrão que é o mesmo valor da variável x quando a função é
definida. Assim, se nenhum valor é fornecido como argumento para a função, ela irá funcionar assim:
Esconder número das linhas
1
2
3
4
5
6
x
y
#
x
y
#
=
=
y
=
=
y
3
s uc o_mac a( ) :
agor a é 8
1
s uc o_mac a( ) :
agor a é 8
Assim - o valor de x não é alterado. Se isto era tudo que nós queríamos, poderíamos simplesmente ter
escrito
Esconder número das linhas
1 def s uc o_t omat e( ) :
2
x = 4
3
r et ur n x * 2
ou mesmo
Esconder número das linhas
1 def s uc o_c enour a( ) :
2
r et ur n 8
Entretanto, o ponto é que o valor de x é obtido do ambiente quando a função é definida. O quanto isto é
útil? Vejamos um exemplo: uma função composta.
Nós queremos uma função que funcione assim:
Esconder número das linhas
1 f r om mat h i mpor t s i n, c os
2 s i nc os = c omponha( s i n, c os )
3 x = s i nc os ( 3)
Onde componha é a função que queremos fazer, e x tem o valor -0.836021861538, que é o mesmo que
sin(cos(3)). Agora, como faremos isto?
(Note que nós estamos usando funções como argumentos... Este é o próprio truque.)
Claramente, componha toma duas funções como parâmetros, e retorna uma função que por sua vez
recebe um parâmetro. Assim, um esqueleto da solução seria:
Esconder número das linhas
1 def c omponha( f un1, f un2) :
2
def i nt er i or ( x ) :
3
pas s # . . .
4
r et ur n i nt er i or
Nós poderíamos tentar return fun1(fun2(x)) dentro da da função interior e deixá-lo tal qual. Não, não, não.
Isto teria um comportamento muito estranho. Imagine o seguinte cenário:
Esconder número das linhas
1
2
3
4
5
6
7
f r om mat h i mpor t s i n, c os
def f un1( x ) :
r et ur n x + " mundo! "
def f un2( x ) :
r et ur n " Ol á, "
s i nc os = c omponha( s i n, c os )
x = s i nc os ( 3)
# Us ando a v er s ão i nc or r et a
Agora, qual valor x terá? Resposta: "Olá, mundo!". Por que isto? Porque quando é chamada, ela toma o
valor de fun1 e fun2 do ambiente, não aqueles de quando foi criada. Para conseguir a solução correta,
tudo que teremos que fazer é usar a técnica descrita anteriormente:
Esconder número das linhas
1 def c omponha( f un1, f un2) :
2
def i nt er i or ( x , f un1=f un1, f un2=f un2) :
3
r et ur n f un1( f un2( x ) )
4
r et ur n i nt er i or
Agora nós só temos que esperar que ninguém forneça mais de um argumento à função resultante, pois
isto quebraria os esquemas :). E, a propósito, já que nós não precisamos do nome interior, e esta função
contém somente uma expressão, nós podemos usar uma função anônima, usando a palavra-chave
lambda:
Esconder número das linhas
1 def c omponha( f 1, f 2) :
2
r et ur n l ambda x , f 1=f 1, f 2=f 2: f 1( f 2( x ) )
Sucinto, porém claro. Você tem que gostar
(E se você não entendeu nada, não se preocupe. Pelo menos eu espero tê-lo convencido que Python é
muito mais do que "uma linguagem para scripts"...
E agora...
Só umas coisinhas para terminar. A maioria das funções e classes mais úteis são colocadas em módulos,
os quais são na verdade arquivos-texto contendo código Python. Você pode importá-los e usá-los em
seus programas. Por exemplo, para usar o método split do módulo padrão string, você pode ter estas
duas formas:
Esconder número das linhas
1 i mpor t s t r i ng
2 x = s t r i ng. s pl i t ( y )
Ou...
Esconder número das linhas
1 f r om s t r i ng i mpor t s pl i t
2 x = s pl i t ( y )
Para mais informações sobre a biblioteca de módulos padrão, de uma olhada em www.python.org/doc/lib.
Contém muitos módulos úteis.
Todo o código em um módulo/script se executa quando é importado. Se você quer que o seu programa
seja tanto um módulo importável quanto um programa executável, você pode adicionar alguma coisa
parecida com isto no final do programa:
Esconder número das linhas
1 i f __name__ == " __mai n__" :
2
ex ec ut ar ( )
Esta é uma forma mágica de dizer que se este módulo esta sendo executado como um script executável
(isto é, que não está sendo importado por outro script), então a função executar deve ser chamada. E é
claro, você poderia fazer qualquer coisa após os dois pontos...
E para aqueles que desejam fazer um script UN*X executável, escreva isto como primeira linha do
arquivo:
Esconder número das linhas
1 #! / us r / bi n/ env py t hon
Finalmente, uma breve menção de um conceito importante: Exceções. Algumas operações (como divisão
por zero ou ler de um arquivo não-existente) produzem condições de erro ou exceções. Você pode até
criar suas próprias exceções e lançá-las em momentos adequados.
Se nada é feito para tratar a exceção, seu programa termina e mostra uma mensagem de erro. Você pode
evitar isto com uma construção try/except. Por exemplo:
Esconder número das linhas
1 def di v i s ao_s egur a( a, b) :
2
t r y:
3
r et ur n a/ b
4
ex c ept Zer oDi v i s i onEr r or :
5
r et ur n None
ZeroDivisionError é uma exceção padrão. Neste caso, você poderia ter verificado se b era zero,
mas em muitos casos, esta estratégia não é viável. Além disso, se não tivermos a cláusula try em
divisao_segura, e dessa forma tornando arriscada a sua chamada, nós poderíamos ainda fazer alguma
coisa assim:
Esconder número das linhas
1 t r y:
2
di v i s ao_i ns egur a( a, b)
3 ex c ept Zer oDi v i s i onEr r or :
4
pr i nt " Foi t ent ada uma di v i s ão por z er o em di v i s ao_i ns egur a"
Nos casos onde normalmente não haveriam problemas específicos, mas eles poderiam ocorrer, o uso de
exceções evita tediosos testes, etc.
Bem - era isto. Espero que você tenha aprendido alguma coisa. Agora pode ir brincar. E lembre-se do
lema do aprendizado em Python: "Use os fontes, Lucas." (Tradução: leia todo código fonte a que você
tiver acesso
Para começar, aqui está um exemplo. É o conhecido algoritmo QuickSort, de Hoare. Uma
versão com a sintaxe destacada em cores está aqui.
Vale a pena mencionar uma coisa sobre este exemplo. A variável done controla se partition foi finalizada,
ou não, na busca entre os elementos. Assim quando um dos dois laços internos querem terminar a
sequência de trocas, eles atribuem 1 à variável done e interrompem-se a si próprios com break. Por que
os laços internos usam done? Porque, quando o primeiro laço interno finaliza com um break, o laço
seguinte só será executado se done não estiver com o valor 1:
Esconder número das linhas
1 whi l e not
2
whi l e
3
#
4
whi l e
5
#
done:
not done:
Repet e- s e at é oc or r er um br eak
not done:
Só ex ec ut ado s e o pr i mei r o não at r i bui r 1 par a " done"
Uma versão equivalente, possivelmente mais clara, mas em minha opinião menos elegante que a anterior
poderia ser:
Esconder número das linhas
1 whi l e not done:
2
whi l e 1:
3
# Repet e- s e at é oc or r er um br eak
4
i f not done:
5
whi l e 1:
6
# Só ex ec ut ado s e o pr i mei r o não at r i bui r
" done"
1 par a
A única razão para eu usar a variável done no primeiro laço foi porque eu preferi manter a simetria entre
os dois laços. Desta forma poderia ser invertida a ordem e mesmo assim o algoritmo funcionaria.
Mais alguns exemplos podem ser encontrados na página tidbitde Joe Strout
Download