Introdução
Nesta parte, analisamos mais de perto a prática de escrever scripts Python.
This tutorial is from open-source community. Access the source code
Nesta parte, analisamos mais de perto a prática de escrever scripts Python.
Um script é um programa que executa uma série de instruções e para.
## program.py
statement1
statement2
statement3
...
Temos escrito principalmente scripts até este ponto.
Se você escrever um script útil, ele crescerá em recursos e funcionalidades. Você pode querer aplicá-lo a outros problemas relacionados. Com o tempo, ele pode se tornar uma aplicação crítica. E se você não tomar cuidado, ele pode se transformar em uma grande bagunça emaranhada. Então, vamos nos organizar.
Nomes devem sempre ser definidos antes de serem usados posteriormente.
def square(x):
return x*x
a = 42
b = a + 2 ## Requires that `a` is defined
z = square(b) ## Requires `square` and `b` to be defined
A ordem é importante. Quase sempre você coloca as definições de variáveis e funções perto do topo.
É uma boa ideia colocar todo o código relacionado a uma única tarefa em um só lugar. Use uma função.
def read_prices(filename):
prices = {}
with open(filename) as f:
f_csv = csv.reader(f)
for row in f_csv:
prices[row[0]] = float(row[1])
return prices
Uma função também simplifica operações repetidas.
oldprices = read_prices('oldprices.csv')
newprices = read_prices('newprices.csv')
Uma função é uma sequência de instruções com um nome.
def funcname(args):
statement
statement
...
return result
Qualquer instrução Python pode ser usada dentro.
def foo():
import math
print(math.sqrt(2))
help(math)
Não existem instruções especiais em Python (o que torna fácil de lembrar).
Funções podem ser definidas em qualquer ordem.
def foo(x):
bar(x)
def bar(x):
statements
## OR
def bar(x):
statements
def foo(x):
bar(x)
As funções só devem ser definidas antes de serem realmente usadas (ou chamadas) durante a execução do programa.
foo(3) ## foo must be defined already
Estilisticamente, é provavelmente mais comum ver funções definidas de forma bottom-up (de baixo para cima).
Funções são tratadas como blocos de construção. Os blocos menores/mais simples vêm primeiro.
## myprogram.py
def foo(x):
...
def bar(x):
...
foo(x) ## Defined above
...
def spam(x):
...
bar(x) ## Defined above
...
spam(42) ## Code that uses the functions appears at the end
Funções posteriores constroem-se sobre funções anteriores. Novamente, este é apenas um ponto de estilo. A única coisa que importa no programa acima é que a chamada para spam(42) venha por último.
Idealmente, as funções devem ser uma caixa preta (black box). Elas devem operar apenas nos inputs passados e evitar variáveis globais e efeitos colaterais misteriosos. Seus principais objetivos: Modularidade e Previsibilidade.
É uma boa prática incluir documentação na forma de uma doc-string (string de documentação). Doc-strings são strings escritas imediatamente após o nome da função. Elas alimentam help(), IDEs e outras ferramentas.
def read_prices(filename):
'''
Read prices from a CSV file of name,price data
'''
prices = {}
with open(filename) as f:
f_csv = csv.reader(f)
for row in f_csv:
prices[row[0]] = float(row[1])
return prices
Uma boa prática para doc strings é escrever um resumo curto de uma frase sobre o que a função faz. Se mais informações forem necessárias, inclua um exemplo curto de uso, juntamente com uma descrição mais detalhada dos argumentos.
Você também pode adicionar dicas de tipo opcionais às definições de função.
def read_prices(filename: str) -> dict:
'''
Read prices from a CSV file of name,price data
'''
prices = {}
with open(filename) as f:
f_csv = csv.reader(f)
for row in f_csv:
prices[row[0]] = float(row[1])
return prices
As dicas não fazem nada operacionalmente. Elas são puramente informativas. No entanto, podem ser usadas por IDEs, verificadores de código e outras ferramentas para fazer mais.
Na seção 2, você escreveu um programa chamado report.py que imprimia um relatório mostrando o desempenho de uma carteira de ações. Este programa consistia em algumas funções. Por exemplo:
## report.py
import csv
def read_portfolio(filename):
'''
Read a stock portfolio file into a list of dictionaries with keys
name, shares, and price.
'''
portfolio = []
with open(filename) as f:
rows = csv.reader(f)
headers = next(rows)
for row in rows:
record = dict(zip(headers, row))
stock = {
'name' : record['name'],
'shares' : int(record['shares']),
'price' : float(record['price'])
}
portfolio.append(stock)
return portfolio
...
No entanto, também havia partes do programa que apenas executavam uma série de cálculos roteirizados. Este código aparecia perto do final do programa. Por exemplo:
...
## Output the report
headers = ('Name', 'Shares', 'Price', 'Change')
print('%10s %10s %10s %10s' % headers)
print(('-' * 10 + ' ') * len(headers))
for row in report:
print('%10s %10d %10.2f %10.2f' % row)
...
Neste exercício, vamos pegar este programa e organizá-lo um pouco mais fortemente em torno do uso de funções.
Modifique seu programa report.py para que todas as operações principais, incluindo cálculos e saída, sejam realizadas por uma coleção de funções. Especificamente:
print_report(report) que imprima o relatório.Pegue a última parte do seu programa e empacote-a em uma única função portfolio_report(portfolio_filename, prices_filename). Faça com que a função funcione de modo que a seguinte chamada de função crie o relatório como antes:
portfolio_report('/home/labex/project/portfolio.csv', '/home/labex/project/prices.csv')
Nesta versão final, seu programa não será nada mais do que uma série de definições de função, seguida por uma única chamada de função para portfolio_report() no final (que executa todas as etapas envolvidas no programa).
Ao transformar seu programa em uma única função, torna-se fácil executá-lo com diferentes entradas. Por exemplo, experimente estas instruções interativamente após executar seu programa:
>>> portfolio_report('/home/labex/project/portfolio2.csv', '/home/labex/project/prices.csv')
... veja a saída ...
>>> files = ['/home/labex/project/portfolio.csv', '/home/labex/project/portfolio2.csv']
>>> for name in files:
print(f'{name:-^43s}')
portfolio_report(name, '/home/labex/project/prices.csv')
print()
... veja a saída ...
>>>
Python torna muito fácil escrever código de script relativamente não estruturado, onde você apenas tem um arquivo com uma sequência de instruções nele. Em termos gerais, é quase sempre melhor utilizar funções sempre que possível. Em algum momento, esse script vai crescer e você desejará ter um pouco mais de organização. Além disso, um fato pouco conhecido é que o Python roda um pouco mais rápido se você usar funções.
Parabéns! Você concluiu o laboratório de Scripting. Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.