Передача списка
149
Printing model: dodecahedron
Printing model:
robot pendant
Printing model: iphone case
The following models have been printed:
dodecahedron
robot pendant
iphone case
Мы можем изменить структуру этого кода: для этого следует написать две функ-
ции, каждая из которых решает одну конкретную задачу. Б
у
льшая часть кода
останется неизменной; просто программа становится более эффективной. Первая
функция занимается печатью, а вторая выводит сводку напечатанных моделей:
def print_models(unprinted_designs, completed_models):
"""
Имитирует
печать моделей, пока список не станет пустым.
Каждая модель после печати перемещается в completed_models.
"""
while unprinted_designs:
current_design = unprinted_designs.pop()
# Имитация печати модели на 3D-принтере.
print("Printing model: " + current_design)
completed_models.append(current_design)
def show_completed_models(completed_models):
"""Выводит информацию обо всех напечатанных моделях."""
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)
В точке
определяется функция
print_models()
с двумя параметрами: список
моделей для печати и список готовых моделей. Функция имитирует печать каж-
дой модели, последовательно извлекая модели из первого списка и перемещая
их во второй список. В точке
определяется функция
show_completed_models()
с одним параметром: списком напечатанных моделей. Функция
show_completed_
models()
получает этот список и выводит имена всех напечатанных моделей.
Программа выводит тот же результат, что и версия без функций, но структура
кода значительно улучшилась. Код, выполняющий б
у
льшую часть работы, разне-
сен по двум разным функциям; это упрощает чтение основной части программы.
Теперь любому разработчику будет намного проще просмотреть код программы
и понять, что делает программа:
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)
150
Глава 8 • Функции
Программа создает список моделей для печати и пустой список для готовых моде-
лей. Затем, поскольку обе функции уже определены, остается вызвать их и передать
правильные аргументы. Мы вызываем
print_models()
и передаем два необходимых
списка; как и ожидалось,
print_models()
имитирует печать моделей. Затем вызыва-
ется функция
show_completed_models()
, и ей передается список готовых моделей,
чтобы функция могла вывести информацию о напечатанных моделях. Благодаря
содержательным именам функций другой разработчик сможет прочитать этот код
и понять его даже без комментариев.
Вдобавок эта программа создает меньше проблем с расширением и сопровождени-
ем, чем версия без функций. Если позднее потребуется напечатать новую партию
моделей, достаточно снова вызвать
print_models()
. Если окажется, что код печати
необходимо модифицировать, изменения достаточно внести в одном месте, и они
автоматически распространятся на все вызовы функции. Такой подход намного
эффективнее независимой правки кода в нескольких местах программы.
Этот пример также демонстрирует принцип, в соответствии с которым каждая
функция должна решать одну конкретную задачу. Первая функция печатает
каждую модель, а вторая выводит информацию о готовых моделях. Такой подход
предпочтительнее решения обеих задач в функции. Если вы пишете функцию
и видите, что она решает слишком много разных задач, попробуйте разделить ее
код на две функции.
Помните, что функции всегда можно вызывать из других функций. Эта возмож-
ность может пригодиться для разбиения сложных задач на серию составляющих.
Запрет
изменения списка в функции
Иногда требуется предотвратить изменение списка в функции. Допустим, у вас
имеется список моделей для печати, и вы пишете функцию для перемещения их
в список готовых моделей, как в предыдущем примере. Возможно, даже после пе-
чати всех моделей исходный список нужно оставить для отчетности. Но, поскольку
все имена моделей были перенесены из списка
unprinted_designs
, остался только
пустой список; исходная версия списка потеряна. Проблему можно решить пере-
дачей функции копии списка вместо оригинала. В этом случае все изменения,
вносимые функцией в список, будут распространяться только на копию, а оригинал
списка остается неизменным.
Чтобы
передать функции копию списка, можно поступить так:
имя_функции
(
имя_списка
[:])
Синтаксис среза
[:]
создает копию списка для передачи функции. Если удаление
элементов из списка
unprinted_designs
в
print_models .py
нежелательно, функцию
print_models()
можно вызвать так:
print_models(unprinted_designs[:], completed_models)
Функция
print_models()
может выполнить свою работу, потому что она все равно
получает имена всех ненапечатаных моделей. Но на этот раз она получает не сам
список
unprinted_designs
, а его копию. Список
completed_models
заполняется
Передача списка
151
именами напечатанных моделей, как и в предыдущем случае, но исходный список
функцией не изменяется.
Несмотря на то что передача копии позволяет сохранить содержимое списка, обыч-
но функциям следует передавать исходный список (если у вас нет веских причин
для передачи копии). Работа с существующим списком более эффективна, потому
что программе не приходится тратить время и память на создание отдельной копии
(лишние затраты особенно заметны при работе с большими списками).
Достарыңызбен бөлісу: