содержание | Предыдущий раздел (2.7 Объектная модель) | Следующий раздел (3.2 Подробные функции)
3.1 Скрипт
В этом разделе мы углубимся в соглашения о написании сценариев Python.
Что такое сценарий?
Скрипт — это программа, которая запускает и завершает серию операторов.
# program.py
statement1
statement2
statement3
...
До сих пор мы в основном были сценарием.
проблема
Если написать полезный скрипт, его возможности и функциональность возрастут. Возможно, вы захотите применить это к связанному вопросу. Со временем это может стать важным приложением. Это может превратиться в беспорядок, если вы не обращаете внимания. Итак, давайте методично организуем наши процедуры.
определить переменную
Имя должно быть определено перед использованием.
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
Порядок важен.
Почти всегда поместите переменные и определения функций в верхней части.
определить функцию
объединить все в одинЗадачаРекомендуется хранить связанный код в одном месте. Этого можно добиться с помощью функций:
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
Функции также могут упростить повторяющиеся операции.
oldprices = read_prices('oldprices.csv')
newprices = read_prices('newprices.csv')
Что такое функция?
Функция — это именованная последовательность операторов.
def funcname(args):
statement
statement
...
return result
любойОператоры Python можно использовать внутри функций.
def foo():
import math
print(math.sqrt(2))
help(math)
Нет в Питонеспециальныйутверждение (что облегчает запоминание).
определение функции
может быть в любом порядкеопределениефункция.
def foo(x):
bar(x)
def bar(x):
statements
# OR
def bar(x):
statements
def foo(x):
bar(x)
Во время выполнения программы функции должны быть определены (вызваны) до того, как они будут фактически использованы.
foo(3) # foo must be defined already
Стилистически функции чаще всего определяются восходящим образом.
восходящий стиль
Функции используются в качестве строительных блоков. Меньшие/простые блоки имеют приоритет.
# 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
Последняя функция основывается на первой функции. Опять же, это всего лишь вопрос стиля. Единственное, что имеет значение в приведенной выше программе, этоspam(42)
Звонок находится на последнем шаге.
функциональный дизайн
В идеале функция должна бытьчерный ящик. Они должны работать только с входными данными и избегать глобальных переменных и странных побочных эффектов. Основные цели: модульность и предсказуемость.
строка документации
Хорошей практикой является включение документации в виде строк документации. Строка документации — это строка, следующая сразу за именем функции. они используются дляhelp()
функции, интегрированные среды разработки и другие инструменты.
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
Хорошей практикой для строки документации является написание короткого предложения, в котором резюмируется, что делает функция. Если требуется дополнительная информация, включите краткий пример использования с более подробным описанием параметров.
введите аннотацию
Необязательные подсказки типа также могут быть добавлены к определениям функций.
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
Подсказка ничего не делает в работе. Они носят чисто информационный характер. Однако интегрированные инструменты разработки, средства проверки кода и другие инструменты могут использовать его для выполнения большего количества операций.
Упражнение
В разделе 2 программа с именемreport.py
Программа, которая печатает отчет, показывающий производительность портфеля акций. Эта программа содержит некоторые функции. Например:
# 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
...
但是,程序的有些部分仅执行一系列的脚本计算。这些代码出现在程序结尾处。 Например:
...
# 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)
...
В этом упражнении мы используем функции, чтобы упорядочить программу и сделать ее более надежной.
Упражнение 3.1. Постройте программу как набор функций
пожалуйста, изменитеreport.py
запрограммировать так, чтобы все основные операции, включая вычисления и вывод, выполнялись набором функций. Особенно:
- Функция для создания отчета о печати
print_report(report)
. - Измените последнюю часть программы так, чтобы это была просто последовательность вызовов функций и никаких других операций не требовалось.
Упражнение 3.2. Создайте функцию верхнего уровня для выполнения программы
Упакуйте последнюю часть программы в одну функциюportfolio_report(portfolio_filename, prices_filename)
середина. Пусть программа запустится, чтобы приведенный ниже вызов функции создал отчет, как и раньше.
portfolio_report('Data/portfolio.csv', 'Data/prices.csv')
В окончательной версии программа представляет собой не что иное, как ряд определений функций, заканчивающихся одной функцией.portfolio_report()
вызов (он выполняет все шаги, задействованные в программе).
Превратив программу в единую функцию, ее легко запускать после разных входных данных. Например, попробуйте эти операторы в интерактивном режиме после запуска программы:
>>> portfolio_report('Data/portfolio2.csv', 'Data/prices.csv')
... look at the output ...
>>> files = ['Data/portfolio.csv', 'Data/portfolio2.csv']
>>> for name in files:
print(f'{name:-^43s}')
portfolio_report(name, 'Data/prices.csv')
print()
... look at the output ...
>>>
инструкция
Python позволяет легко писать относительно неструктурированные сценарии в файлах с рядом операторов. В общем, всегда, когда это возможно, обычно лучше использовать функции как можно больше. В какой-то момент сценарий будет расти, и мы хотим, чтобы он был более организованным. Кроме того, малоизвестным фактом является то, что Python работает немного быстрее, если вы используете функции.
содержание | Предыдущий раздел (2.7 Объектная модель) | Следующий раздел (3.2 Подробные функции)
Примечание. Полный перевод см.GitHub.com/co Статья 3 — /PRA…