Introdução
À medida que seus programas começam a ficar maiores, você desejará se organizar. Esta seção introduz brevemente funções e módulos de biblioteca. O tratamento de erros com exceções também é introduzido.
This tutorial is from open-source community. Access the source code
À medida que seus programas começam a ficar maiores, você desejará se organizar. Esta seção introduz brevemente funções e módulos de biblioteca. O tratamento de erros com exceções também é introduzido.
Use funções para código que você deseja reutilizar. Aqui está uma definição de função:
def sumcount(n):
'''
Retorna a soma dos primeiros n inteiros
'''
total = 0
while n > 0:
total += n
n -= 1
return total
Para chamar uma função:
a = sumcount(100)
Uma função é uma série de instruções que executam alguma tarefa e retornam um resultado. A palavra-chave return é necessária para especificar explicitamente o valor de retorno da função.
Python vem com uma grande biblioteca padrão. Módulos de biblioteca são acessados usando import. Por exemplo:
import math
x = math.sqrt(10)
import urllib.request
u = urllib.request.urlopen('http://www.python.org/')
data = u.read()
Cobriremos bibliotecas e módulos com mais detalhes mais tarde.
Funções relatam erros como exceções. Uma exceção faz com que uma função seja abortada e pode fazer com que todo o seu programa pare se não for tratada.
Tente isso no seu REPL Python.
>>> int('N/A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'N/A'
>>>
Para fins de depuração, a mensagem descreve o que aconteceu, onde o erro ocorreu e um traceback mostrando as outras chamadas de função que levaram à falha.
Exceções podem ser capturadas e tratadas.
Para capturar, use a instrução try - except.
for line in file:
fields = line.split(',')
try:
shares = int(fields[1])
except ValueError:
print("Couldn't parse", line)
...
O nome ValueError deve corresponder ao tipo de erro que você está tentando capturar.
É frequentemente difícil saber exatamente que tipos de erros podem ocorrer com antecedência, dependendo da operação que está sendo realizada. Para o bem ou para o mal, o tratamento de exceções geralmente é adicionado depois que um programa travou inesperadamente (ou seja, "ah, esquecemos de capturar esse erro. Devemos tratá-lo!").
Para levantar uma exceção, use a instrução raise.
raise RuntimeError('What a kerfuffle')
Isso fará com que o programa seja abortado com um traceback de exceção. A menos que seja capturado por um bloco try-except.
% python3 foo.py
Traceback (most recent call last):
File "foo.py", line 21, in <module>
raise RuntimeError("What a kerfuffle")
RuntimeError: What a kerfuffle
Tente definir uma função simples:
>>> def greeting(name):
'Issues a greeting'
print('Hello', name)
>>> greeting('Guido')
Hello Guido
>>> greeting('Paula')
Hello Paula
>>>
Se a primeira instrução de uma função for uma string, ela serve como documentação. Tente digitar um comando como help(greeting) para vê-la exibida.
Pegue o código que você escreveu para o programa pcost.py no Exercício 1.27 e transforme-o em uma função portfolio_cost(filename). Esta função recebe um nome de arquivo como entrada, lê os dados do portfólio nesse arquivo e retorna o custo total do portfólio como um float.
Para usar sua função, altere seu programa para que ele se pareça com isto:
## pcost.py
def portfolio_cost(filename):
"""
Computes the total cost (shares*price) of a portfolio file
"""
total_cost = 0.0
with open(filename, "rt") as f:
rows = f.readlines()
headers = rows[0].strip().split(",")
for row in rows[1:]:
row_data = row.strip().split(",")
nshares = int(row_data[1])
price = float(row_data[2])
total_cost += nshares * price
return total_cost
import sys
if len(sys.argv) == 2:
filename = sys.argv[1]
else:
filename = input("Enter a filename:")
cost = portfolio_cost(filename)
print("Total cost:", cost)
Quando você executar seu programa, deverá ver a mesma saída de antes. Depois de executar seu programa, você também pode chamar sua função interativamente digitando isto:
$ python3 -i pcost.py
Isso permitirá que você chame sua função do modo interativo.
>>> portfolio_cost('portfolio.csv')
44671.15
>>>
Poder experimentar seu código interativamente é útil para testes e depuração.
O que acontece se você tentar sua função em um arquivo com alguns campos ausentes?
>>> portfolio_cost('missing.csv')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pcost.py", line 11, in portfolio_cost
nshares = int(fields[1])
ValueError: invalid literal for int() with base 10: ''
>>>
Neste ponto, você se depara com uma decisão. Para fazer o programa funcionar, você pode ou sanitizar o arquivo de entrada original, eliminando as linhas ruins, ou pode modificar seu código para lidar com as linhas ruins de alguma forma.
Modifique o programa pcost.py para capturar a exceção, imprimir uma mensagem de aviso e continuar processando o restante do arquivo.
Python vem com uma grande biblioteca padrão de funções úteis. Uma biblioteca que pode ser útil aqui é o módulo csv. Você deve usá-lo sempre que precisar trabalhar com arquivos de dados CSV. Aqui está um exemplo de como ele funciona:
>>> import csv
>>> f = open('portfolio.csv')
>>> rows = csv.reader(f)
>>> headers = next(rows)
>>> headers
['name', 'shares', 'price']
>>> for row in rows:
print(row)
['AA', '100', '32.20']
['IBM', '50', '91.10']
['CAT', '150', '83.44']
['MSFT', '200', '51.23']
['GE', '95', '40.37']
['MSFT', '50', '65.10']
['IBM', '100', '70.44']
>>> f.close()
>>>
Uma coisa boa sobre o módulo csv é que ele lida com uma variedade de detalhes de baixo nível, como citação e divisão adequada por vírgulas. Na saída acima, você notará que ele removeu as aspas duplas dos nomes na primeira coluna.
Modifique seu programa pcost.py para que ele use o módulo csv para análise (parsing) e tente executar os exemplos anteriores.
No programa pcost.py, o nome do arquivo de entrada foi codificado no código:
## pcost.py
def portfolio_cost(filename):
...
## Your code here
...
cost = portfolio_cost('portfolio.csv')
print('Total cost:', cost)
Isso é bom para aprendizado e testes, mas em um programa real você provavelmente não faria isso.
Em vez disso, você pode passar o nome do arquivo como um argumento para um script. Tente alterar a parte inferior do programa da seguinte forma:
## pcost_1.33.py
import csv
def portfolio_cost(filename):
"""
Computes the total cost (shares*price) of a portfolio file
"""
total_cost = 0.0
with open(filename, "rt") as f:
rows = csv.reader(f)
headers = next(rows) ## Skip header row
for row in rows:
if len(row) < 3:
print("Skipping invalid row:", row)
continue
try:
nshares = int(row[1])
price = float(row[2])
total_cost += nshares * price
except (IndexError, ValueError):
print("Skipping invalid row:", row)
return total_cost
import sys
if len(sys.argv) == 2:
filename = sys.argv[1]
else:
filename = 'portfolio.csv'
cost = portfolio_cost(filename)
print('Total cost:', cost)
sys.argv é uma lista que contém os argumentos passados na linha de comando (se houver).
Para executar seu programa, você precisará executar o Python a partir do terminal.
Por exemplo, no bash no Unix:
$ python3 pcost.py portfolio.csv
Total cost: 44671.15
bash %
Parabéns! Você concluiu o laboratório de Funções. Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.