Перевод: "Практическое программирование на Python" 03_01_Script

Python

содержание | Предыдущий раздел (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…