Você está na página 1de 104

Aprendendo Python

Um curso em programação

Per Kraulis

Traduzido para português e


com conteúdo extendido por
Antonio e Tiago Borges – iNCE/UFRJ
2011
Sobre Python
O que é Python?
Uma linguagem de programação Primeiro lançamento: Fevereiro de 1991
- Caracterísiticas de Perl e Java, com Versão atual: 2.3
influência de C, C++, Scheme,
Haskell, Smalltalk, Ada, Simula,. Evolutiva política por mudanças
Open Source entre versões
- Livre; código-fonte aberto São raros os problemas de incompatibilidade
- Baixe no seu próprio sistema com versões anteriores
Escrito por Guido van Rossum - Mas elas existem.
Monty Python's Flying Circus. - Maiores mudanças: de 1.5 para 2.0
Recursos do Python

Uma linguagem de script Mensagens de erro úteis


interpretedas Gerenciamento de memória automática
- Não compila/fase link Independente do sistema operacional
- Escreve e executa - Trabalha em ambos Unix e Windows
- Lento comparado ao C, C++ - Even file system code can be made
Design elegante; "tight" os-independent

Projetado para Grande biblioteca de módulos padrão


- Scripts rápidos Grande número de módulos feitos
- Módulos reutilizáveis por terceiros
- Sistemas muito grandes
Integração com código externo C
Orientação a objetos Bem documenteda
- Muito bem designada
-Mas você não tem que usá-la
Livros sugeridos

Learning Python (Lutz & Ascher) – 4ª. edição


- Tutorial
- Covers Python 2.x e 3.x
- Deve ser lido em sequência, mas pulando trechos da parte 1
- Muitos pontos úteis sobre estilo de programação

Python in a Nutshell (Martelli)


- Referência Rápida
- Livro complementar da documentação online
- Leitura em seqüência: só “nerds”
Python sob Windows:
diversos ambientes

Use a janela de comando de linha do Python (para trabalho interativo)


Ou, edite usando editor comum (notepad) e duplo-clique no arquivo
Python para executar
-Não há problema se a saída for gráfica
-Problema comum: ao fim da execução a janela se fecha sozinha.
- Colocar um “raw_input” ao final do programa

Ambientes interativos: para editar e executar scripts


IDLE
PythonWin
Deficientes visuais: pyvox
Vamos usar IDLE nesse curso

Interface gráfica do usuário (GUI)

Desenvolvimento interativo
Ambiente (IDE) para Python

Funciona sob Windows e Unix

Não é fundamental; use outro editor


Se você quiser

Escrita em Python, usando Tk

Nome homenagem a Eric Idle, membro do


Monty Python
Mensagem inicial do IDLE
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 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 2.6.5
>>>

Modo interativo:
- Aguarda comandos do usuário
- Os comandos devem ser válidos no código Python
- Útil para testar e mexer

Tentar os comandos:
- copyright
- credits
- license()
Python em Unix

% python
Python 2.3.3 (#51, Dec 18 2003, 20:22:39).
Type "copyright", "credits" or "license()" for more information.
>>> print “Olá Mundo!"
Olá Mundo!
>>>

Use qulquer editor (vi, ed, emacs, gedit...)para editar e executar arquivos de script
Use o IDLE para editar e executar arquivos de script

% python script.py
.result output.
%

% vi script.py # edite o arquivo.


% cat script.py
#!/usr/local/bin/python # nota: a mágica da primeira linha
print "Hello world!"
%
% chmod ugo+x script.py # torna o arquivo executável
%
% script.py
Hello world!
%
Parte 1:
Variáveis e Tipos de Construção
Hello world!

>>> print ‘Olá mundo!'


Olá mundo!

>>> a = ‘Olá mundo!'


>>> print a
Olá mundo!
Variáveis e tipos
>>> a = ‘Olá Mundo!' # está é uma instrução de atribuição
>>> print a
‘Olá mundo!'

Variáveis são criadas quando são atribuídas


Nenhuma declaração é exigida
O nome da variável é sensível a maiúsculas: 'val' não é o mesmo que 'Val'
O tipo da variável é determinada pelo Python
Uma variavél pode ser atribuída novamente a qualquer coisa,

>>> n = 12 >>> n = 'apa'


>>> print n >>> print n
12 'apa'
>>> type(n) >>> type(n)
<type 'int'> <type 'str'>

>>> n = 12.0
>>> type(n)
<type 'float'>
Números
Integers: 12 0 -12987 0123 0X1A2
- Type 'int'
- Podem ser maiores que 2**31
- Literais octais começam com 0 (0981 é ilegal!)
- Literais hexadecimais começam com 0X, contem 0-9 e A-F

Ponto Flutuante: 12.03 1E1 -1.54E-21


- Tipo 'float'
- Mesma precisão e magnitude que o C++

Inteiros Longos: 10294L


- Tipo 'long'
- Qualquer magnitude
- Python em geral lida bem com conversões de int para long

Números complexos: 1+3J


- Type 'complex'
Expressões numéricas
Os usuais operadores de expressão numéricos: +, -, /, *, **, %, //
Precedência e parênteses funcionam como esperado

>>> 12+5 >>> 4 + 5.5


17 9.5
>>> 12+5*2 >>> 1 + 3.0**2
22 10.0
>>> (12+5)*2 >>> 1+2j + 3-4j
34 (4-2j)

Lista completa: ver "Aprendendo Python"

>>> a=12+5
>>> print a
17
>>> b = 12.4 + a # 'a' convertido para “float” automaticamente
>>> b # utiliza função 'repr'
29.399999999999999
>>> print b # utiliza função 'str'
29.4
Expressões booleanas
‘True' ou ' False' são valores pré-definidos; atualmente inteiros 1 e 0
O Valor 0 é considerado falso, e todos os outros valores verdadeiros
Expressões booleanas operadores usuais: not, and, or

>>> True or False


True
>>> not ((True and False) or True)
False
>>> True * 12
12
>>> 0 and 1
0
Os operadores de comparação produzem valores booleanos
Exemplos comuns : <, <=, >, >=, ==, !=

>>> 12<13
True
>>> 12>13
False
>>> 12<=12
True
>>> 12!=13
True
String
>>> a = ‘Olá mundo !'
>>> b = “Olá !"
>>> a == b
True

>>> a = “ Leitura Per's"


>>> print a
leitura Per's
Aspas simples ou duplas podem ser usadas para strings literais
Produzem exatamente o mesmo valor
Caracteres especiais em strings literais: \n newline, \t tab, others

>>> a = "One line.\nAnother line."


>>> print a
One line.
Another line.

>>> b = """One line,


another line."""
>>> print b
One line,
another line.
Conversões String
>>> a = "58" >>> f = float('1.2e-3')
>>> type(a) >>> f # uses 'repr'
<type 'str'> 0.0011999999999999999
>>> b=int(a) >>> print f # uses 'str'
>>> b 0.0012
58 >>> eval('23-12')
>>> type(b) 11
<type 'int'>

Converter arquivos de dados usando as funções 'str', 'int', 'float'


'repr' é uma variação de 'str'
- Destinado para casos específicos, códigos do tipo representação de valores
- 'str' normalmente apresenta boa representação gráfica

A Função 'eval' interpreta uma string como uma expressão Python

>>> c = int('blah') # O que acontece quando alguma coisa ilegal é feita?


Traceback (arquivo mais recente chamado):
File "<pyshell#34>", line 1, in -toplevel-
c = int('blah')
ValueError: invalid literal for int(): blah
Operações mais comuns com Strings

>>> a = "Part 1"


>>> b = "and part 2"
>>> a + ' ' + b # concatenação, adicionando strings
'Part 1 and part 2'
>>> s = a * 2 # repete e concatena a string
>>> print s
Part 1Part 1

>>> s[0] # index: Um único caractere, compensação 0 (zero)


'P'
>>> s[0:4] # slice: parte de uma string
'Part'
>>> s[5:] # Deixar um limite: para o fim
'1Part 1'
>>> >>> s[6:-1] # index negativo contagem para o fim
'Part '

>>> len(s) # função 'len' para obter o tamanho da string


12
>>> 'p' in s # Testar adesão
False
>>> 'P' in s
True
>>> 'Part' in s # também funciona para substrings (novo recurso)
True
Alterando strings. Não!

>>> s[0] = 'B'


Traceback (most recent call last):
File "<pyshell#68>", line 1, in -toplevel-
s[0] = 'B'
TypeError: object doesn't support item assignment

Uma string não pode ser alterada in Python! Imutável


Boas razões para isto: mais tarde
Criar novas strings a partir de pedaços e peças do antigo

>>> s = 'B' + s[1:]


>>> s
'Bart 1Part 1'

Recriar strings pode usar bastante poder computacional


Se você precisar criar muitas strings novas, aprenda formatação de strings (mais tarde)

A lista de processamento quase sempre pode ser usada para fazer a manipulação de strings mais eficiente
Métodos de String
Strings têm um conjunto de métodos de construção
Nunca nenhum método muda a string original
Vários métodos produzem novas strings
Uma lista na página 91 em ‘Aprendendo Python'

>>> s = 'a string, with stuff'


>>> s.count('st') # Quantas substrings?
2
>>> s.find('stu') # dá a localização da substring, se houver alguma
15
>>> three = '3'
>>> three.isdigit() # Digita somente caracteres na string?
True

>>> supper = s.upper() # converte para caixa alta


>>> supper
'A STRING, WITH STUFF'
>>> s.rjust(30) # Justifica à direita adicionando espaços em branco
' a string, with stuff'
>>> "newlines\n\n\n".strip() # Uma string literal também tem métodos!
'newlines'

>>> s.replace('stuff', 'characters') # substitui substrings (todas as ocorrências)


'a string, with characters'
>>> s.replace('s', 'X', 1) # substitui apenas uma vez
'a Xtring, with stuff'
Lista
Compilação ordenada de objetos; matriz
Heterogênea; pode conter uma mistura de objetos de vários tipos

>>> r = [1, 2.0, 3, 5] # lista literal; diferentes tipos de valores


>>> r
[1, 2.0, 3, 5]
>>> type(r)
<type 'list'>

>>> r[1] # acesso pelo index; deslocamento 0 (zero)


2.0
>>> r[-1] # index negativo conta a partir do final
5

>>> r[1:3] # um trecho de uma lista, dá uma outra lista


[2.0, 3]

>>> w = r + [10, 19] # concatena listas; dá outra lista


>>> w
[1, 2.0, 3, 5, 10, 19]
>>> r # lista original inalterada; w e r são diferentes
[1, 2.0, 3, 5]

>>> t = [0.0] * 10 #cria um vetor inicial usando repetição


>>> t
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
Operações de lista
Listas são mutáveis; podem ser alteradas na posição
Listas são dinâmicas; o tamanho pode ser alterado

>>> r = [1, 2.0, 3, 5]


>>> r[3] = 'word' #altera um ítem pelo índice
>>> r
[1, 2.0, 3, 'word']

>>> r[0] = [9, 8] # listas podem ser aninhadas


>>> r
[[9, 8], 2.0, 3, 'word']

>>> r[0:3] = [1, 2, 5, 6] # alterar uma parte da lista; pode mudar o seu comprimento
>>> r
[1, 2, 5, 6, 'word']
>>> r[1:3] = [] # Remover itens de parte da configuração para uma lista vazia
>>> r
[1, 6, 'word']

>>> len(r) # Comprimento da lista; número de itens


3

>>> 6 in r # Teste de membros


True
>>> r.index(6) # busca pela posição; falha se o ítem não estiver na lista
1
Métodos de lista, parte 1
As listas tem um conjunto de métodos de constução
Alguns métodos alteram a lista em seu lugar

>>> r = [1, 2.0, 3, 5]


>>> r.append('thing') # adiciona um único item para o final
>>> r
[1, 2.0, 3, 5, 'thing']
>>> r.append(['another', 'list']) # lista é tratada com um único item
>>> r
[1, 2.0, 3, 5, 'thing', ['another', 'list']]

>>> r = [1, 2.0, 3, 5]


>>> r.extend(['item', 'another']) #itens da lista são anexados um por um
>>> r
[1, 2.0, 3, 5, 'item', 'another']

>>> k = r.pop() #remove o último item da lista e retorna


>>> k
'another'
>>> r
[1, 2.0, 3, 5, 'item']
Os métodos 'append' e 'pop' podem ser usados para implementar uma pilha
Métodos de lista, parte 2
Use o método de construção 'sort' : eficiente
A lista é ordenada em sua posição; não é produzida uma nova lista

>>> r = [2, 5, -1, 0, 20]


>>> r.sort()
>>> r
[-1, 0, 2, 5, 20]

>>> w = ['apa', '1', '2', '1234']


>>> w.sort() # strings: ordenação lexical usando comando ASCII
>>> w
['1', '1234', '2', 'apa']

>>> w.reverse() # como inverter uma lista; em sua posição!


>>> w
['apa', '2', '1234', '1']

>>> v = w[:] Primeiramente cria-se uma cópia da lista


>>> v.reverse() # em seguida inverte-se a cópia
>>> v # use a mesma técnica para classificar
['1', '1234', '2', 'apa']
>>> w
['apa', '2', '1234', '1']
Convertendo listas entre strings
>>> s = 'biovitrum' # cria uma string
>>> w = list(s) # converte para uma lista de chars
>>> w
['b', 'i', 'o', 'v', 'i', 't', 'r', 'u', 'm']
>>> w.reverse()
>>> w
['m', 'u', 'r', 't', 'i', 'v', 'o', 'i', 'b']
>>> r = ''.join(w) # agrega usando a string vazia
>>> r
'murtivoib'
>>> d = '-'.join(w) # agrega usando “tracinhos”
>>> d
'm-u-r-t-i-v-o-i-b'

>>> s = 'a few words'


>>> w = s.split() # Divide em espaços em branco(blank, newline)
>>> w
['a', 'few', 'words']
'split' é útil para análise simples
Em outros casos use o módulo de expressão regular 're'; mais tarde

>>> ' | '.join(w) # Usa qualquer string com o método 'join'


'a | few | words'
Objetos, nomes e referências
Todos os valores são objetos
Uma variável é um nome referenciado a um objeto
Um objeto pode ter vários nomes referenciando-o
quando modificando os objetos por posição
Você pode ter que fazer suas próprias cópias para obter o efeito desejado
Para objetos imutáveis (números, strings), isso nunca é um problema

a
>>> a = [1, 3, 2]
>>> b = a [1, 3, 2]
>>> c = b[0:2]
>>> d = b[:] b

c [1, 3]

d [1, 3, 2]

>>> b.sort() # 'a' é afetado!


>>> a
[1, 2, 3]
Tupla
O mesmo que lista, exceto imutável
Uma vez criada, não pode ser alterada
Algumas funções retornam tuples

>>> t = (1, 3, 2)
>>> t[1] # acesso pelo index; início em 0 (zero)
3

>>> (a, b, c) = t # atribuição tuple(descompactar)


>>> a
1
>>> b
3
>>> a, b, c # Na verdade, uma expressão tuple!
(1, 3, 2)

>>> a, b = b, a # um truque enxuto para trocar valores


>>> a, b
(3, 1)

>>> r = list(t) # converte tuple para a lista


>>> r
[1, 3, 2]
>>> tuple(r) # converte a lista para tuple
(1, 3, 2)
Dicionário
Uma coleção desordenada de chaves/valor pares
Cada chave mapeia para um valor
Também chamado "mapeamento", “tabela hash " ou “ tabela lookup "

>>> h = {'key': 12, 'nyckel': 'word'}


>>> h['key'] # acesso pela chave
12
>>> h.has_key('nyckel')
True

>>> h['Per'] = 'Kraulis' # adicionando uma chave/valor


>>> h
{'nyckel': 'word', 'Per': 'Kraulis', 'key': 12} # a ordem de saída é aleatória
>>> h['Per'] = 'Johansson' # substitui o valor
>>> h
{'nyckel': 'word', 'Per': 'Johansson', 'key': 12}
A chave é
- Normalmente um integral ou uma string
- Deve (aconselhável!) ser um objeto imutável
- Pode ser qualquer objeto do tipo 'hashable' (mais tarde)
- Qualquer chave ocorre no máximo uma vez em um dicionário!

O valor deve ser qualquer objeto


- Os valores devem ocorrer várias vezes
Esquecendo coisas: 'del'
Use o comando 'del' para se livras de coisas
Comando! Não é função!
Atualmente remove variáveis(nomes), não objetos

>>> a = 'thing' # define uma variável


>>> a
'thing'
>>> del a # esquece a variável
>>> a
Traceback (most recent call last):
File "<pyshell#182>", line 1, in -toplevel-
a
NameError: name 'a' is not defined

>>> h = {'key': 12, 'nyckel': 'word'}


>>> del h['key'] # remove a chave e seu valor
>>> h
{'nyckel': 'word'}

>>> r = [1, 3, 2]
>>>
itemsdel r[1] # outra forma de remover a lista
>>> r
[1, 2]
Esquecendo coisas: Coleta de lixo

O que acontece com a memória quando um objeto é deletado, ou


atribuído a um outro objeto?

O sistema Python detecta quando um objeto é perdido no espaço


Ele mantém uma lista de registros do número de
referências a ele

A memória do objeto permanece com o conteúdo: de tempos em


tempos: Coleta de lixo

Alguns problemas em casos especiais; referências cíclicas


Métodos de dicionário, parte 1
>>> h = {'key': 12, 'nyckel': 'word'}
>>> 'Per' in h # testa se a chave está no dicionário
False
>>> h['Per']
Traceback (most recent call last):
File "<pyshell#192>", line 1, in -toplevel-
h['Per']
KeyError: 'Per'

>>> h.get('Per', 'unknown') # Valor retorna padrão se não for encontrado


'unknown'
>>> h.get('key', 'unknown')
12

>>> h.keys() # todas as chaves na lista; desordenado


['nyckel', 'key']
>>> h.values() # todos os valores na lista; desordenado
['word', 12]

>>> len(h) # número de chaves no dicionário


2
Métodos de dicionário, parte 2
>>> g = h.copy() # Uma cópia separada do dicionário
>>> del h['key']
>>> h
{'nyckel': 'word'}
>>> g
{'nyckel': 'word', 'key': 12}

>>> h['Per'] = 'Johansson'


>>> h
{'nyckel': 'word', 'Per': 'Johansson'}
>>> h.update(g) # adicionar ou atualizar todas as chaves/valores a partir de g
>>> h
{'nyckel': 'word', 'key': 12, 'Per': 'Johansson'}
Formatando strings
Operador para formatar string '%'
Na verdade a melhor forma de criar novas strings
Formatação C-like: Um pouco complexa, mas poderosa
Muitas strings formatando códigos
- %s: string (usa função 'str')
- %r: string (usa função 'repr')
- %f, %e, %g: float

>>> w = "Number %i won!" % 12 # Operador de formatação de string %


>>> w
'Number 12 won!'

Tuples são usadas como operandos na formatação de strings >1 item


O comprimento do tuple deve corresponder ao número de códigos de formatação da string
As listas não vão fazer!

>>> c = 'Python'
>>> n = 11
>>> "This is a %s course with %i students." % (c, n)
'This is a Python course with 11 students.'
Parte 2:
Fluxos de execução básicos
'if' declaração; estrutura do bloco
A estrutura do bloco é determinada pela indentação

Editar um novo arquivo script 't2.py'


- Na janela 't1.py' proceda 'File', 'New Window', depois 'Save As.

Use a declaração 'if'

"file t2.py"

person = 'Luke'

if person == 'Per':
status = 'Pythonist'
elif person == 'Luke':
status = 'Jedi knight'
else:
status = 'unknown'

print person, status

Note que o editor do IDLE ajuda com a indentação


Execute o script (F5)
Igualdade entre objetos
Dois tipos de igualdade:
- Os dois objetos são semelhantes em valor?
- As duas referências estão realmente apontando para o mesmo objeto

>>> a = [1, 2]
>>> b = [1, 2]
>>> a == b # testa se os valores são iguais
True
>>> a is b # teste se objetos são idênticos
False
>>> a.append(3)
>>> a == b # testa valores novamente
False
Dicionário: às vezes melhores que if... elif.

Particularmente com muitas opções (elif's).

"file t3.py"

status_map = {'Luke': 'Jedi Knight', 'Per': 'Pythonist'}


person = 'Luke'
print person, status_map.get(person, 'unknown')

Mais compacto, e mais eficiente


Este padrão é muito útil
Tipos de construção e suas interpretações booleanas

int 0 False
Todos os tipos “built-in’’ podem ser usados
-1 True diretamente em declarações 'if'

124 True
Números com valor zero são falsos
float 0.0 False Todos os outros números são verdadedeiros

str "" False


Caixas vazias (str, list, dict) são Falsas
"False" True ! Todos os outros valores de caixas são
verdadeiros
dict {} False
Use a função 'bool' para obter valores explícitos
{'key': 'val'} True

list [] False

[False] True !
Declaração 'for'
Repetição de um bloco de declarações
Iteração através de uma sequência (list, tuple, string, iterator)

"file t4.py"

s=0
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8]: # walk through list, assign to i
s=s+i
if s > 10:
break # quit 'for' loop, jump to after it

print "i=%i, s=%i" % (i, s)

"file t5.py"

r = []
for c in 'this is a string with blanks': # walks through string, char by char
if c == ' ': continue # skip rest of block, continue loop
r.append(c)
print ''.join(r)
Funções“Built-in”: 'range' and 'xrange'
As funções “Built-in” ‘range' e 'xrange' são úteis com 'for'
'range' cria uma lista
Cuidado: pode usar muita memória; ineficiente!

>>> range(9) # start=0, step=1 by default


[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> range(1, 12, 3) # explicit start, end, step
[1, 4, 7, 10]
>>> range(10**9) # Erro de memória!
'xrange' cria um iterador, que trabalha como uma lista
- veremos iteradores mais adiante
Mais eficiente quando muitos números
"file t6.py"

s=0
for i in xrange(100000):
if i % 19 == 0: # remanescente: divisível com 19?
s=s+i
print s
Declaração 'while'
Repetição de um bloco de declarações
Repete até o teste se tornar falso, ou 'break'

"file t7.py"

r = []
n=0
last = 20

while n <= last: # Qualquer expressão é interpretada como booleana


r.append(str(n))
n += 3

print ', '.join(r)


Opcional: 'else' em blocos em loop
‘bloco else‘ executado se não for encontrado 'break‘
Pode muitas vezes substituir testes de sucesso/falha
Válido em loops 'for' e 'while'

"file t8.py"

r = [1, 3, 10, 98, -2, 48]

for i in r:
if i < 0:
print 'input contains negative value!'
break # this skips out of loop, including 'else'
else:
pass # do-nothing statement
else: # do if loop ended normally
print 'input is OK'

A declaração 'pass‘ não faz absolutamente nada


Pode ser útil como espaço reservado para o código não escrito
Há alguns casos onde são necessários (mais tarde)
Manuseio de erros: 'try' e 'except'
Erros de execuçao normalmente fazem a execuçao abortar.
A mensagem de erro mostra o que aconteceu
Use blocos 'try‘ ... 'except' para capturar e manusear os erros

"file t9.py"

numbers = []
not_numbers = []

for s in ['12', '-4.1', '1.0e2', 'e3']:


try:
n = float(s)
numbers.append(s)
except ValueError, msg:
not_numbers.append(str(msg))

print 'numbers:', numbers


print 'not numbers:', not_numbers

numbers: ['12', '-4.1', '1.0e2']


not numbers: ['invalid literal for float(): e3']
Como dividir linhas longas
Algumas vezes uma linha do código-fonte precisa dividir-se
Regra de indentação significa que nós não temos formato livre

“Exemplo de sintaxe ilegal"

if a_complicated_expression and
another_complicated_expression:
print ‘isso é uma sintaxe ilegal; isso não irá funcionar'
Alt 1: Use o caracter de continuação '\' como o último

“Sintaxe válida, exemplo 1"

if a_complicated_expression and \
another_complicated_expression:
print ‘isso é uma sintaxe válida'
Alt 2: Coloque a expressão em parenteses
- Linhas em parenteses podem ser quebradas
- Também é verdadeiro para [ ] e { }

“Sintaxe válida, exemplo 2"

if (a_complicated_expression and
another_complicated_expression):
print ‘esta é uma sentença válida'
Parte 3:
Funções
Como definir sua própria função
Use a declaração 'def'
Função do corpo segue; indentada!
Essa é uma declaração como outras
- Pode ser substituída basicamente em qualquer lugar
- Required: Define a função antes de chamá-la

"file t10.py"

def all_items_positive(r): # definição da função


"Check that all values in list r are positive." # documentação da string
for i in r:
if i <= 0: return False # retorna o valor resultante
return True

sequences = [[1, 5, 6, -0.01], [0.01, 1, 2]]

for seq in sequences:


if not all_items_positive(seq): # chama a função
print 'invalid: ', seq
Recursos da função

O valor de um argumento não é verificado pelo tipo


- Quase sempre muito útil; sobrecarrega sem esforço
- É claro, a função deve permanecer “bomb” se é dado um valor inválido

A string da documentação não é necessária (mais tarde)


- Mas fortemente incentivada!
- Crie o hábito de escrever uma (antes de escrever a função do código)

Uma função definida pelo usuário tem exatamente o mesmo status que uma
função construída, ou uma função de outro módulo
Argumentos de função: fixos
Número fixo de argumentos
Associados por ordem

"file t11.py"

def fixed_args(a, c, b): # nota!: ordem de argumentos


"Format arguments into a string and return." # doc string
return "a=%s, b=%s, c=%s" % (a, b, c) # '%s‘ converte para string

print fixed_args('stuff', 1.2, [2, 1])


Argumentos de função: variáveis
Lista de algum número de argumentos
Útil quando se desconhece o número de argumentos necessários
Os valores de argumento coletados em uma tupla
- chamado 'args', por convenção
- O '*' é a parte mágica

"file t12.py"

def unspec_args(a, *args): # nome 'args' é uma convenção


return "a=%s, others=%s" % (a, args)

print unspec_args('bla', 'qwe', 23, False)

a=bla, others=('qwe', 23, False)


Argumentos de função: Valores padrão
Argumentos devem ter valores padrão
Quando o argumento não é dado em uma chamada, valor padrão é utilizado
Se não houver valor padrão, e não for dado quando é chamado: acontece algo inesperado
Use nomes explícitos para anular ordem de argumentos

"file t13.py"

def default_args(a, b='bar', c=13):


return "a=%s, b=%s, c=%s" % (a, b, c)

print default_args('apa') # usa todos os valores padrão


print default_args('s', b='py') # anula um valor padrão
print default_args(c=-26, a='apa') # anula ordem de argumentos

a=apa, b=bar, c=13


a=s, b=py, c=13
a=apa, b=bar, c=-26
Argumentos de funções: keywords
Palavras-chaves/argumentos de valor
Os valores do argumento coletados em um dicionário
- Chamados 'kwargs', por convenção
- Os '**' são a parte mágica
- As primeiras tentativas para combinar nomes de argumentos existentes

"file t14.py"

def keyword_args(a, b='bla', **kwargs):


return "a=%s, b=%s, kwargs=%s" % (a, b, str(kwargs))

print keyword_args('stuff', c='call')


print keyword_args('stuff', c='call', b='apa')
print keyword_args(c='call', d=12, a='gr')

a=stuff, b=bla, kwargs={'c': 'call'}


a=stuff, b=apa, kwargs={'c': 'call'}
a=gr, b=bla, kwargs={'c': 'call', 'd': 12}
Argumentos de função: Verificação de tipo explícito
Use a declaração 'assert'
Verifique se a expressão booleana é verdadeira, senão algo inesperado acontece
Pode ser usado para verificações de sanidade em qualquer lugar do código
Mensagem explicativa opcional (ou dados)

"file t15.py"

def fixed_args(a, c, b):


assert type(a) == int, "'a' deve ser um inteiro"
return "a=%s, b=%s, c=%s" % (a, b, c)

print fixed_args('a', 1.2, [2, 1])

Traceback (most recent call last):


File "C:\Python tests\t15.py", line 8, in -toplevel-
print fixed_args('a', 1.2, [2, 1])
File "C:\Python tests\t15.py", line 5, in fixed_args
assert type(a) == int, "'a' deve ser um inteiro"
AssertionError: 'a' must be an integer
Argumentos de função: variáveis locais
Argumentos se tornam variáveis locais
- Os valores imutáveis são copiados,com efeito
- Valores mutáveis ainda podem ser modificados: tenha cuidado

Variáveis criadas dentro do bloco 'def' são locais


- Esquecidas no retorno

"file t16.py"

def test_local(a, r):


print 'local original ', a, r
a = 12
r[1] = 999
print 'local changed ', a, r

a = -5
r = [0, 1, 2]
print 'global original', a, r
test_local(a, r)
print 'global changed ', a, r

global original -5 [0, 1, 2]


local original -5 [0, 1, 2]
local changed 12 [0, 999, 2]
global changed -5 [0, 999, 2]
Função sem 'return': nenhum valor
Uma função não tem que usar a declaração 'return'
Se não, é o mesmo que uma 'procedure' em outras linguagens
Na verdade retorna um valor de qualquer jeito: 'None'
Uma 'return' sem valor está OK: retorna 'None'
'None' é um valor especial que significa 'nada'
- Útil em muitos contextos
- Particularmente em programação a objetos orientados (mais tarde)

"file t17.py"

def concat_strings(a, b):


str_type = type('') # salvar um tipo de valor!
if type(a) == str_type and type(b) == str_type:
return a + ' ' + b

print 'strings:', concat_strings('first', 'second')


print 'integers:', concat_strings(1, 2)

strings: first second


integers: None
O ´módulo 'math': funções e constantes
Um breve olhar sobre os módulos
As funções matemáticas disponíveis em um módulo separado

"file t18.py"

from math import * # importa tudo a partir do módulo 'math'

print e, pi
print cos(radians(180.0))
print log(10.0)
print exp(-1.0)

2.71828182846 3.14159265359
-1.0
2.30258509299
0.367879441171
Funções são objetos; nomes e referências
Uma função é somente outro tipo de objeto
Nada mágico sobre os nomes deles; podem ser alterados

"file t19.py"

from math import *

def print_calc(f):
print "log(%s)=%s, exp(%s)=%s" % (f, log(f), f, exp(f))

print_calc(1.0)
log, exp = exp, log # código horrível! troca os objetos e nomes encaminhados
print_calc(1.0)

log(1.0)=0.0, exp(1.0)=2.71828182846
log(1.0)=2.71828182846, exp(1.0)=0.0
Uma função pode ser passada como qualquer argumento para outra função
Uma função pode ser atribuída à uma variável
Função de construção 'map'
Função de construção que funciona em uma lista
'map‘ requer uma função e uma lista
- A função deve aceitar somente um argumento e retornar um valor
- A função é aplicada para cada valor da lista
- Os valores resultantes retornam em uma lista

>>> from math import *


>>> r = [0, 1, 2, 3, 4, 5, 6]
>>> map(cos, r)
[1.0, 0.54030230586813977, -0.41614683654714241, -0.98999249660044542,
-0.65364362086361194, 0.28366218546322625, 0.96017028665036597]
Função de construção 'reduce'
Função de construção que funciona em uma lista
'reduce' requer uma função e uma lista
Tudo se resume em um valor usando a função
- A função deve ter somente dois argumentos, e retornar um valor
- 'reduce' aplica a função aos dois primeiros valores da lista
- A função é então aplicada ao resultado e ao próximo valor na lista
- E assim por diante, até que todos os valores na lista sejam utilizados

>>> r = [0, 1, 2, 3, 4, 5, 6]
>>> def sum(x, y):
return x+y
>>> reduce(sum, r) # (((((1+2)+3)+4)+5)+6)
21
Função de construção 'filter'
Função de construção que funciona em uma lista
'filter' requer uma função e uma lista
Usa a função para decidir quais valores colocar na lista resultante
- Cada valor na lista é dado para a a função
- Se a fução retornar True, então o valor é colocado na lista resultante
- Se a função retornar False, então o valor é ignorado

>>> r = [0, 1, 2, 3, 4, 5, 6]
>>> def large(x):
return x>3
>>> filter(large, r)
[4, 5, 6]
Arquivos: Leitura
O objeto de arquivo é criado pela função de construção 'open'
O objeto de arquivos tem um conjunto de métodos
Os métodos 'read‘ obtém dados sequencialmente a partir do arquivo
- 'read': Obtém o arquivo inteiro (ou N bytes) e volta com uma única string
- 'readline': Lê uma linha (até e incluindo novas linhas)
- 'readlines':Lê todas as linhas e volta como uma lista de strings

>>> f = open('test.txt') # por padrão: modo somente leitura


>>> line = f.readline() # Lê uma única linha
>>> line
'This is the first line.\n'
>>> lines = f.readlines() # lê todas as linhas restantes
>>> lines
['This is the second.\n', 'And third.\n']

Vários módulos definem objetos que são file-like, ou seja,


tem métodos que fazem eles se comportarem como arquivos
Arquivos: Escrevendo
O método 'write' simply sai da string dada
A string não tem que ser ASCII; conteúdo binário permitido

>>> w = open('output.txt', 'w') # Modo write (texto padrão)


>>> w.write('stuff') # Não adiciona newline automaticamente
>>> w.write('\n')
>>> w.write('more\n and even more\n')
>>> w.close()

stuff
more
and even more
Arquivos: lidos pelo laço 'for'
Iteração usando o laço 'for' no arquivo, lê linha por linha
A melhor maneira de fazê-lo

"file t20.py"

infile = open('test.txt') # read-only mode


outfile = open('test_upper.txt', 'w') # write mode; creates the file

for line in infile:


outfile.write(line.upper())

infile.close() # not strictly required; done automatically


outfile.close()

Nota: Cada linha conterá um caracter de nova linha '\n'


Use o método string 'strip' ou 'rstrip' para se livrar dele
Arquivos, estilo-antigo estratégias de leitura
Versões de Python anteriores não tinham o recurso 'for line in file'
Em vez disso, as seguintes alternativas foram utilizadas:

for line in infile.readlines(): # lê o arquivo inteiro na lista de linhas


do_something(line)

for line in infile.xreadlines(): # Como xrange: mais memória-eficiente


do_something(line)

line = infile.readline()
while line: # linha estará vazia somente no final do arquivo
do_something(line)
line = infile.readline()

A última alternativa funciona porque 'readline' retorna a linha, incluindo


A nova linha final '\n' character
Somente quando finais-de-arquivos são alcançados uma linha completamente vazia é
devolvida, o que torna o valor booleano 'False'
Parte 4:
Módulos
Exemplo: a inversão da sequência complementar NT
Dada uma sequência de nucleotídeos, produz o complemento reverso
Usa recursos disponíveis

"file t21.py"

complement_map = {'c': 'g', 'g': 'c', 'a': 't', 't': 'a'}

seq = 'cgtaacggtcaggttatattt'

complist = map(complement_map.get, seq)


complist.reverse()
revseq = ''.join(complist)

print seq
print revseq

cgtaacggtcaggttatattt
aaatataacctgaccgttacg
Tornar o código mais reutilizável
Como fazer o exemplo de código mais reutilizável?
Passo nº 1: Fazer uma função

"file t22.py"

complement_map = {'c': 'g', 'g': 'c', 'a': 't', 't': 'a'}

def reverse_complement(seq):
complist = map(complement_map.get, seq)
complist.reverse()
return ''.join(complist)

seq = 'cgtaacggtcaggttatattt'
print seq
print reverse_complement(seq)
Faça um módulo do código
Como tornar o código mais reutilizável?
Passo nº 2: Fazer um módulo fora dele
Na verdade, já é um módulo!
Vamos simplesmente renomeá-lo como 'ntseq.py'

"""file ntseq.py

Module 'ntseq': operations on NT sequences.


"""

complement_map = {'c': 'g', 'g': 'c', 'a': 't', 't': 'a'}

def reverse_complement(seq):
"Return the reverse complement of an NT sequence."
complist = map(complement_map.get, seq)
complist.reverse()
return ''.join(complist)

seq = 'cgtaacggtcaggttatattt'
print seq
print reverse_complement(seq)
Como usar o módulo: declaração 'import'
A declaração 'import' faz um módulo disponível
O nome do módulo(não o nome do arquivo) é importado: ignora o '.py'
Acessa recursos do módulo através da notação 'dot'

"file t23.py"

import ntseq

seq = 'aaaccc'
print seq
print ntseq.reverse_complement(seq)

cgtaacggtcaggttatattt
aaatataacctgaccgttacg
aaaccc
gggttt

Problema!!!
Primeiras duas linhas: O código de teste no módulo também foi executado
Módulo de código auto-teste: o truque '__name__'
A declaração 'import‘ executa todos os códigos no arquivo de módulo
Como esconder o código auto-teste?
Use a variável predefinida'__name__':
- Se executada como valor principal: valor '__main__'
- Se executada como módulo: algum outro valor

"""file ntseq_mod.py

Module 'ntseq_mod': operations on NT sequences.


"""

complement_map = {'c': 'g', 'g': 'c', 'a': 't', 't': 'a'}

def reverse_complement(seq):
"Return the reverse complement of an NT sequence."
complist = map(complement_map.get, seq)
complist.reverse()
return ''.join(complist)

if __name__ == '__main__': # Código para testar a função


seq = 'cgtaacggtcaggttatattt'
print seq
print reverse_complement(seq)
Agora, o comportamento da declaração 'import'

"file t24.py"

import ntseq_mod # nota: ntseq_mod!

seq = 'aaaccc'
print seq
print ntseq_mod.reverse_complement(seq) # nota: ntseq_mod!

aaaccc
gggttt
Como os módulos são buscados no 'import'?
'import' busca nos diretórios listados em sys.path
É usado o primeiro arquivo encontrado 'xxx.py' (onde xxx é o nome importado)

"file t25.py"

import sys

for dirname in sys.path:


print dirname

M:\My Documents\Python course\tests


C:\Python23\Lib\idlelib
C:\WINNT\system32\python23.zip
C:\Python23
C:\Python23\DLLs
C:\Python23\lib
C:\Python23\lib\plat-win
C:\Python23\lib\lib-tk
C:\Python23\lib\site-packages

Há formas permanentes de mudar sys.path, mas pode-se mudar no programa,


explicitamente, numa atribuição
Módulos são fáceis, divertidos, e poderosos
A função Módulo é a base para a capacidade do Python em atingir
realmente grandes sistemas de software

Fácil para criar: Todo arquivo código-fonte Python é um módulo!

Funções para fazer um módulo elegante:


- Doc strings
- '__name__' trick
- Namespace concept

Certifique-se de ver os módulos da biblioteca padrão!


- Você irá encontrar coisas extremamente úteis lá
- Você vai aprender bons hábitos de códigos

Pacotes são diretórios de vários módulos associados


- Não abordado neste curso. Poucos pontos interessantes
Namespaces
Um namespace é um saco de nomes
Um módulo é um namespace
Use a função de construção 'dir' para listar os nomes em um namespace
Declaração 'import' modifica o namespace

"file t26.py"

for name in dir():


print "%r: %r" % (name, eval(name))
print
print 'virgin namespace:', dir()

import ntseq_mod
print 'after import:', dir()

from ntseq_mod import *


print 'after from:', dir()

'__builtins__': <module '__builtin__' (built-in)>


'__doc__': 'file t26.py'
'__name__': '__main__'

virgin namespace: ['__builtins__', '__doc__', '__name__', 'name']


after import: ['__builtins__', '__doc__', '__name__', 'name', 'ntseq_mod']
after from: ['__builtins__', '__doc__', '__name__', 'complement_map', 'name',
'ntseq_mod', 'reverse_complement']
Evitando a desordem em seu namespace
Usando ‘do módulo import*' pode-se criar confusão
Ajuste-fino de importação; traz somente as coisas selecionadas
Renomeia coisas de um módulo
- Evita conflitos de nome
- Torna mais claro

"file t27.py"

print ‘namespace virgem:', dir()

from math import exp


from math import log as natural_logarithm

print ‘import seletivo:', dir()


print 'exp(1.0)=', exp(1.0)
print 'natural_logarithm(10.0)=', natural_logarithm(10.0)

namespace virgem: ['__builtins__', '__doc__', '__name__']


import seletivo: ['__builtins__', '__doc__', '__name__', 'exp', 'natural_logarithm']
exp(1.0)= 2.71828182846
natural_logarithm(10.0)= 2.30258509299
As variáveis especiais'__xxx__'

Em Python, os nomes das variáveis'__xxx__' são especiais


Dois sublinhados '_' em cada extremidade de uma palavra
Algumas são criados automaticamente durante execução
- __name__, __file__, __doc__, __builtins__
Algumas controlam a execução de diferentes maneiras
Somente defina o valor de uma quando você souber o que está fazendo!
Não use esse tipo de nome para seu próprio material!
Doc strings: '__doc__'
Nós tínhamos mencionado a documentação de strings anteriormente
- A primeira string em um módulo
- A primeira string após uma declaração 'def'

Acessadas através de variáveis'__doc__'


Recurso para facilitar a criação de documentação
- Usado por ferramentas para produzir documentação, tais como 'pydoc'
- Veja 'Module Docs' em ‘iniciar' > 'Programas' > 'Python 2.3'

>>> import ntseq_mod


>>> print ntseq_mod.__doc__
file ntseq_mod.py

Módulo 'ntseq': operações em sequências NT.

>>> print ntseq_mod.reverse_complement.__doc__


Retorna o complemento reverso de uma sequência NT.
Recursos de documentação
Manual do Python
- ‘iniciar' > 'Programas' > 'Python 2.3' > 'Python Manuals'
- Tutorial
- Referência de linguagem (material pesado)
- Módulo Global Index (muito útil)

O Módulo Docs (pydoc)


- Na verdade listas que estão no seu sistema, incluindo todas as três partes do pacote
(se estiver incluído no módulo)
- Usa as strings __doc__ no código-fonte do módulo

www.python.org
- Ponteiros para outros sites

"Use a fonte, Luke."


- Às vezes, o próprio código-fonte pode ser muito útil
Parte 5:
Programação de orientação a objetos,
classes
Classes vs. objetos (instâncias)
Uma classe pode ser vista como um
- Estrutura de informações
- Protótipo
- Criador de objetos

Uma classe define objetos em potencial


- O que serão suas estruturas de dados
- O que elas poderão fazer (métodos)

Objetos são instâncias de uma classe


- Um objeto é uma caixa de dados: atributos
- Um objeto tem funções associadas: métodos
Um exemplo de classe: Formas geométricas
Vamos definir classes por formas geométricas
- Como dado; posição, etc
- Com funções: área computada, etc

"file geom1.py: Módulo com classes por formas geométricas, 1st try"

import math

class Circle: #declaração de definição de classe


"A 2D circle." # documentação de string

def __init__(self, x, y, radius=1): # inicialização do método


self.x = x # programa os atributos desta instância
self.y = y
self.radius = radius

def area(self):
"Return the area of the shape."
return math.pi * self.radius**2
Instâncias de classes
Vamos criar algumas instâncias de classes circulares
Observe o atributo 'radius'
Use o método 'area'

"file t28.py"

from geom1 import *

i1 = Circle(0, 2) # '__init__' é chamada automaticamente


i2 = Circle(3, 0, 4)

print 'i1:', i1.radius, i1.area()


print 'i2:', i2.radius, i2.area()
print str(i1)

i1: 1 3.14159265359
i2: 4 50.2654824574
<geom1.Circle instance at 0x009CEA08>

Circle Circle
i1 x=0 i2 x=3
y=2 y=0
radius=1 radius=4
Mudando uma instância: atribuição de atributos
Os valores dos atributos podem ser modificados
Simplismente atribuindo ao atributo um outro valor

"file t29.py"

from geom1 import *

i1 = Circle(0, 2)
print 'i1:', i1.radius, i1.area()

i1.radius = 2.5 # Muda o valor de um atributo


print 'i1:', i1.radius, i1.area()

i1: 1 3.14159265359
i1: 2.5 19.6349540849
Mudando uma instância: referências
Variáveis podem referenciar o mesmo objeto
Mudar um atributo, modifica o objeto, não a referência

"file t30.py" Circle


i1 x=0
from geom1 import * y=2
radius=1
i1 = Circle(0, 2) i3
i2 = Circle(-1, -1, 4)
i3 = i1

i1.radius = 1.75 Circle


i2 x=-1
print 'i1:', i1.radius
y=-1
print 'i2:', i2.radius radius=4
print 'i3:', i3.radius

i1: 1.75
i2: 4
i3: 1.75
Mudando uma instância: status do atributo
Attributes are local to the instance
Atributos podem programar qualquer coisa

"file t31.py"

from geom1 import *

i1 = Circle(0, 2, 4)
print 'i1:', i1.radius, i1.area()
i1.radius = -2
print 'i1:', i1.radius, i1.area()
i1.radius = 'garbage'
print 'i1:', i1.radius, i1.area()

i1: 4 50.2654824574
i1: -2 12.5663706144
i1: garbage
Traceback (most recent call last):
File "M:/My Documents/Python course/tests/t31.py", line 10, in -toplevel-
print 'i1:', i1.radius, i1.area()
File "M:/My Documents/Python course/tests\geom1.py", line 15, in area
return math.pi * self.radius**2
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
Mudando uma instância: atribuir add/delete
Um atributo pode ser acrescentado!
And deleted!

"file t32.py"

from geom1 import *

i1 = Circle(0, 2)

i1.colour = 'red' # adiciona um atributo de instância


print 'i1:', i1.radius, i1.colour

del i1.radius # deleta um atributo de instância


print 'has i1 radius?', hasattr(i1, 'radius') # funçaõ de construção
print 'i1:', i1.area()

i1: 1 red
has i1 radius? False
i1:
Traceback (most recent call last):
File "M:/My Documents/Python course/tests/t32.py", line 11, in -toplevel-
print 'i1:', i1.area()
File "M:/My Documents/Python course/tests\geom1.py", line 15, in area
return math.pi * self.radius**2
AttributeError: Circle instance has no attribute 'radius'
Inspecionando objetos: dir
Use a função de contrução 'dir' para inspecionar objetos
'__doc__': string de documentação de classe
'__class__': classe para a instância

>>> import geom1


>>> i1 = geom1.Circle(0, 0, 2)
>>> dir(i1)
['__doc__', '__init__', '__module__', 'area', 'radius', 'x', 'y']
>>> print i1.__doc__
A 2D circle.
>>> print i1.__class__
geom1.Circle

>>> type(i1)
<type 'instance'>
>>> type(Circle)
<type 'classobj'>
>>> type(i1.radius)
<type 'int'>
>>> type(i1.area)
<type 'instancemethod'>
Métodos especiais em classes
Métodos especiais '__xxx__' em classes
Define comportamento sob medida

"file geom2.py: Module with classes for geometrical shapes, 2nd try"

import math

class Circle:
# ...alguns códigos foram removidos aqui, para esclarecer...

def __repr__(self): # melhor representação de string


return "Circle(%g, %g, radius=%g)" % (self.x, self.y, self.radius)

def __nonzero__(self): # é um círculo verdadeiro? outro ponto


return self.radius != 0

def __cmp__(self, other): # compara a outro: maior ou não?


return cmp(self.radius, other.radius)
Usando os métodos especiais, parte 1
Definições de métodos especiais são detectadas pelo Python
As funções de construção usam eles; ver documentação

"file t33.py"

from geom2 import *

i1 = Circle(0, 2.5)
i2 = Circle(3, 4.02, 0)

print str(i1)
print 'is i1 a circle?:', bool(i1)
print 'is i2 a circle?:', bool(i2)
print 'i1 larger than i2?', i1 > i2 # usa __cmp__, se definido

Circle(0, 2.5, radius=1)


is i1 a circle?: True
is i2 a circle?: False
i1 larger than i2? True
Usando métodos especiais, parte 2
Definir métodos especiais pode esclarecer o código tremendamente
Mas: permaneça racional 'natural'!

"file t34.py"

from geom2 import *

circles = [Circle(1, 3),


Circle(0, 0, 0.2),
Circle(-1, -1, 10.0)]
print circles # this uses 'repr', which calls __repr__

circles.sort() # this uses 'cmp', which calls __cmp__


print circles

[Circle(1, 3, radius=1), Circle(0, 0, radius=0.2), Circle(-1, -1, radius=10)]


[Circle(0, 0, radius=0.2), Circle(1, 3, radius=1), Circle(-1, -1, radius=10)]
Herança: Hierarquias de classe
Vamos definir uma classe geral 'Shape'
'Circle' é um caso especial de 'Shape'
'Blob' também é um caso especial de 'Shape'
Aviso: Redefinição de 'is_round' está em 'Blob'

"file geom3.py: Module with classes for geometrical shapes, 2nd try"

import math

class Shape: # Essa é uma classe base


"General geometrical shape."

def is_round(self):
return True

class Circle(Shape): # circle é herança de shape


# ...same code as in geom2.py...

class Blob(Shape):
"An undefined blob."

def is_round(self): # substitui método de shape


return False
Instances of classes using inheritance
Which method is called by which instance?
Polymorphism
Selection of method depends on actual class of the instance
Extremely powerful, if properly designed class hierarchy

"file t35.py"

from geom3 import *

shapes = [Shape(),
Circle(1, -2),
Blob()]

for s in shapes:
print s, 'round?', s.is_round()

<geom3.Shape instance at 0x009CEF80> round? True


Circle(1, -2, radius=1) round? True
<geom3.Blob instance at 0x009CEF58> round? False
Example: Handle sequences, part 1
"file bioseq.py Module to handle NT or AA sequences. Incomplete."

class Bioseq:

def __init__(self, seq=None):


self.seq = seq

def fetch(self, acc):


pass # to be defined in inheriting classes

class Nucleotide(Bioseq):

def fetch(self, acc):


pass # code to fetch from EMBL; cause IOError if not

def translate(self):
pass # code to translate NT seq to AA
return Protein(seq='whatever')

class Protein(Bioseq):

def fetch(self, acc):


pass # code to fetch from Swiss-Prot; cause IOError
Example: Handle sequences, part 2
Write a help function for fetching either 'Nucleotide' or 'Protein'
This is a so-called factory function
"file t36.py"

from bioseq import *

def fetch_seq(acc):
for cls in [Nucleotide, Protein]:
try:
result = cls()
result.fetch(acc)
return result
except IOError:
pass
return None

print fetch_seq('A123')
<bioseq.Nucleotide instance at 0x009CEFA8>
Parte 6:
Módulos de biblioteca padrão
Módulo 're', parte 1
Expressões regulares: padrões avançados de string
Define um padrão
- A sintaxe padrão é muito parecida com Perl or grep

Aplique-o a uma string


Processe os resultados

"file t37.py"

import re

seq = "MAKEVFSKRTCACVFHKVHAQPNVGITR"

zinc_finger = re.compile('C.C..H..H') # compila padrão de expressão regular


print zinc_finger.findall(seq)

two_charged = re.compile('[DERK][DERK]')
print two_charged.findall(seq)

['CACVFHKVH']
['KE', 'KR']
Módulo 'sys', parte 1
Variáveis e funções para o interpretador Python

sys.argv
- Lista de argumentos de linhas de comando; sys.argv[0] é um nome script
sys.path
- Lista de nomes de diretórios, onde os módulos são procurados
sys.platform
- String para identificar o tipo de sistema do computador

>>> import sys


>>> sys.platform
'win32'
Módulo 'sys', parte 2

sys.stdout, sys.stdin, sys.stderr


- Pré-define “file objects” para entrada/saída
- Material 'print' vai para'sys.stdout'
- Pode ser ajustado a outros arquivos
sys.exit(n)
- Força a saída da execução Python
- 'n‘ é um erro de código inteiro, normalmente 0

>>> import sys


>>> sys.stdout.write('the hard way')
the hard way
Módulo 'os', parte 1
Interface portável para serviços de sistemas operacionais

os.getcwd()
- Retorna ao diretório atual

>>> os.getcwd()
'M:\\My Documents\\Python course\\tests'

os.environ
- Dicionário contendo as variáveis de ambiente atual

>>> for k, v in os.environ.items(): print k, v

TMP C:\DOCUME~1\se22312\LOCALS~1\Temp
COMPUTERNAME WS101778
USERDOMAIN BIOVITRUM
COMMONPROGRAMFILES C:\Program Files\Common Files
PROCESSOR_IDENTIFIER x86 Family 6 Model 9 Stepping 5, GenuineIntel
PROGRAMFILES C:\Program Files
PROCESSOR_REVISION 0905
HOME C:\emacs
...
Módulo 'os', parte 2
os.chdir(path)
- Muda o diretório de trabalho atual para 'path'

os.listdir(path)
- Retorna uma lista de conteúdos do diretório 'path'

os.mkdir(path)
- Cria o diretório 'path'

os.rmdir(path)
- Remove o diretório 'path'

os.remove(path)
- Remove o arquivo chamado 'path'
Module 'os', parte 3

os.system(comando)
- Executa o comando shell (string) em um subprocesso
- Retorna o código de erro como inteiro
os.popen(command, mode='r')
- Executa o comando shell (string)
- Abre uma pipe para o comando, retorna como objeto de arquivo
- Modo é somente leitura, ou escrita; não ambos
os.popen2, os.popen3, os.popen4
- Variações de os.popen, com diferentes objetos de arquivo

os.getpid()
- Retorna o processo ID como inteiro
Módulo 'os.path', parte 1
Path portável manipulação de nome

os.path.abspath(path)
- Retorna ao ‘path’ absoluto para o atribuído 'path’ relativo

>>> d = os.path.abspath('.')
>>> d
'M:\\My Documents\\Python course\\tests'

os.path.dirname(path)
- Retorna a parte do nome do diretório 'path'

>>> os.path.dirname(d)
'M:\\My Documents\\Python course'
Módulo 'os.path', parte 2
os.path.join(path, path, .)
- Agrupa as partes do path inteligentemente para um nome path válido
>>> d = os.path.join(os.getcwd(), 't1.py')
>>> d
'M:\\My Documents\\Python course\\tests\\t1.py'

os.path.split(path)
- Divide-se o path para um nome de diretório e nome de arquivo
- Contrário de 'os.path.join'

>>> os.path.split(d)
('M:\\My Documents\\Python course\\tests', 't1.py')
os.path.splitext(path)
- Divide-se o path para nome de arquivo base e a extensão (se houver alguma)

>>> >>> os.path.splitext(d)


('M:\\My Documents\\Python course\\tests\\t1', '.py')
Módulo 'os.path', parte 3
os.path.exists(path)
- O 'path' existe? Arquivo, ou diretório

>>> d = os.path.join(os.getcwd(), 't1.py')


>>> os.path.exists(d)
True

os.path.isfile(path)
'path‘ é o nome de um arquivo?
os.path.isdir(path)
'path‘ é o nome de um diretório?

>>> os.path.isfile(d)
True
>>> os.path.isdir(d)
False

os.path.walk(path, func, arg)


- Usado para processar uma árvore de diretório inteira
- Visita cada subdiretório
- Chama a função 'func' com uma lista de nome de arquivos naquele dirétório
Alguns outros módulos úteis
shutil 'shell utilities': copia arquivos, remove diretórios inteiros

StringIO Objetos similares a strings que se comportam como arquivos


cStringIO
gzip, zipfile Pega os arquivos comprimidos
dbm, gdbm Arquivos que se comportam como dicionários ; bases de dados simples

time manipulador e formatador de tempo


random Gerador de números aleatórios
urlparse Manipulação de endereço URL
urllib, urllib2 Busca dados URL, usando como objetos file-like
ftplib Manipulador de FTP
cgi Operações de script CGI
Tkinter Interface para Tk/Tcl; módulo de interface gráfica do usuário(GUI)
xml Pacote para manipular arquivos XML

Você também pode gostar