Книга Изучаем Python
Скачать 4.68 Mb.
|
133 repeat = input("Would you like to let another person respond? (yes/ no) ") if repeat == 'no': polling_active = False # Опрос завершен, вывести результаты. print("\n--- Poll Results ---") for name, response in responses.items(): print(name + " would like to climb " + response + ".") Сначала программа определяет пустой словарь ( responses ) и устанавливает флаг ( polling_active ), показывающий, что опрос продолжается. Пока polling_active содержит True , Python будет выполнять код в цикле while В цикле пользователю предлагается ввести имя и название горы, на которую ему хотелось бы подняться . Эта информация сохраняется в словаре responses в строке , после чего программа спрашивает у пользователя, нужно ли продол- жать опрос . Если пользователь отвечает положительно, то программа снова входит в цикл while . Если же ответ отрицателен, флаг polling_active переходит в состояние False , цикл while перестает выполняться, и завершающий блок кода выводит результаты опроса. Если вы запустите эту программу и введете пару ответов, результат будет выгля- деть примерно так: What is your name? Eric Which mountain would you like to climb someday? Denali Would you like to let another person respond? (yes/ no) yes What is your name? Lynn Which mountain would you like to climb someday? Devil's Thumb Would you like to let another person respond? (yes/ no) no --- Poll Results --- Lynn would like to climb Devil's Thumb. Eric would like to climb Denali. УПРАЖНЕНИЯ 7-8 . Сэндвичи: создайте список с именем sandwich_orders, заполните его названиями раз- личных видов сэндвичей . Создайте пустой список с именем finished_sandwiches . В цикле переберите элементы первого списка и выведите сообщение для каждого элемента (напри- мер, «I made your tuna sandwich») . После этого каждый сэндвич из первого списка пере- мещается в список finished_sandwiches . После того как все элементы первого списка будут обработаны, выведите сообщение с перечислением всех изготовленных сэндвичей . 7-9 . Без пастрами: используя список sandwich_orders из упражнения 7-8, проследите за тем, чтобы значение ‘pastrami’ встречалось в списке как минимум три раза . Добавьте в на- чало программы код для вывода сообщения о том, что пастрами больше нет, и напишите цикл while для удаления всех вхождений ‘pastrami’ из sandwich_orders . Убедитесь в том, что в finished_sandwiches значение ‘pastrami’ не встречается ни одного раза . 7-10 . Отпуск мечты: напишите программу, которая опрашивает пользователей, где бы они хотели провести отпуск . Включите блок кода для вывода результатов опроса . 134 Глава 7 • Ввод данных и циклы while Итоги В этой главе вы научились использовать input() для того, чтобы пользователи могли вводить собственную информацию в своих программах. Вы научились рабо- тать с числовыми и текстовыми данными, а также управлять продолжительностью выполнения своих программ с помощью циклов while . Также мы рассмотрели несколько способов управления циклами while : установку флага, команду break и команду continue . Вы узнали, как использовать цикл while для перемещения элементов из одного списка в другой и как удалить все вхождения некоторого значения из списка. Также были рассмотрены возможности применения циклов while со словарями. Глава 8 посвящена функциям. Функции позволяют разделить программу на мень- шие части, каждая из которых решает одну конкретную задачу. Функции можно хранить в отдельных файлах и вызывать их столько раз, сколько потребуется. Благодаря функциям вы сможете писать более эффективный код, более простой в отладке и сопровождении, который к тому же можно повторно использовать в разных программах. 8 Функции Эта глава посвящена функциям — именованным блокам кода, предназначенным для решения одной конкретной задачи. Чтобы выполнить задачу, определенную в виде функции, вы указываете имя функции, отвечающей за эту задачу. Если зада- ча должна многократно выполняться в программе, вам не придется заново вводить весь необходимый код; просто вызовите функцию, предназначенную для решения задачи, и этот вызов приказывает Python выполнить код, содержащийся внутри функции. Как вы вскоре убедитесь, использование функций упрощает чтение, на- писание, тестирование кода и исправление ошибок. В этой главе также рассматриваются возможности передачи информации функ- циям. Вы узнаете, как писать функции, основной задачей которых является вывод информации, и другие функции, предназначенные для обработки данных и возвра- щения значения (или набора значений.) Наконец, вы научитесь хранить функции в отдельных файлах, называемых модулями, для упорядочения файлов основной программы. Определение функции Вот простая функция greet_user() , которая выводит приветствие: greeter.py def greet_user(): """Выводит простое приветствие.""" print("Hello!") greet_user() В этом примере представлена простейшая структура функции. Строка при по- мощи ключевого слова def сообщает Python, что вы определяете функцию. В опре- делении функции указывается имя функции и, если нужно, описание информации, необходимой функции для решения ее задачи. Эта информация заключается в круглые скобки. В данном примере функции присвоено имя greet_user() , и она не нуждается в дополнительной информации для решения своей задачи, поэтому круглые скобки пусты. (Впрочем, даже в этом случае они обязательны.) Наконец, определение завершается двоеточием. Все строки с отступами, следующие за def greet_user(): , образуют тело функ- ции. Текст в точке представляет собой комментарий — строку документации 136 Глава 8 • Функции с описанием функции. Строки документации заключаются в утроенные кавычки; Python опознает их по этой последовательности символов во время генерирования документации к функциям в ваших программах. «Настоящий» код в теле этой функции состоит всего из одной строки print("Hello!") — см. . Таким образом, функция greet_user() решает всего одну задачу: выполнение команды print("Hello!") Когда потребуется использовать эту функцию, вызовите ее. Вызов функции при- казывает Python выполнить содержащийся в ней код. Чтобы вызвать функцию, укажите ее имя, за которым следует вся необходимая информация, заключенная в круглые скобки, как показано в строке . Так как никакая дополнительная ин- формация не нужна, вызов функции эквивалентен простому выполнению команды greet_user() . Как и ожидалось, функция выводит сообщение Hello! : Hello! Передача информации функции С небольшими изменениями функция greet_user() сможет не только сказать «Привет!» пользователю, но и поприветствовать его по имени. Для этого следует включить имя username в круглых скобках в определение функции def greet_ user() . С добавлением username функция примет любое значение, которое будет заключено в скобки при вызове. Теперь функция ожидает, что при каждом вызове будет передаваться имя пользователя. При вызове greet_user() укажите имя (на- пример, 'jesse' ) в круглых скобках: def greet_user(username): """Выводит простое приветствие.""" print("Hello, " + username.title() + "!") greet_user('jesse') Команда greet_user('jesse') вызывает функцию greet_user() и передает ей информацию, необходимую для выполнения команды print . Функция получает переданное имя и выводит приветствие для этого имени: Hello, Jesse! Точно так же команда greet_user('sarah') вызывает функцию greet_user() и передает ей строку 'sarah' , что приводит к выводу сообщения Hello, Sarah! Функцию greet_user() можно вызвать сколько угодно раз и передать ей любое имя на ваше усмотрение — и вы будете получать ожидаемый результат. Аргументы и параметры Функция greet_user() определена так, что для работы она должна получить значение переменной username . После того как функция будет вызвана и полу- чит необходимую информацию (имя пользователя), она выведет правильное приветствие. Передача аргументов 137 Переменная username в определении greet_user() — параметр, то есть условные данные, необходимые функции для выполнения ее работы. Значение 'jesse' в greet_user('jesse') — аргумент, то есть конкретная информация, переданная при вызове функции. Вызывая функцию, вы заключаете значение, с которым функция должна работать, в круглые скобки. В данном случае аргумент 'jesse' был передан функции greet_user() , а его значение было сохранено в переменной username ПРИМЕЧАНИЕ Иногда в литературе термины «аргумент» и «параметр» используются как синонимы . Не удив- ляйтесь, если переменные в определении функции вдруг будут названы аргументами, а значения, переданные при вызове функции, — параметрами . УПРАЖНЕНИЯ 8-1 . Сообщение: напишите функцию display_message() для вывода сообщения по теме, рас- сматриваемой в этой главе . Вызовите функцию и убедитесь в том, что сообщение выво- дится правильно . 8-2 . Любимая книга: напишите функцию favorite_book(), которая получает один пара- метр title . Функция должна выводить сообщение вида «One of my favorite books is Alice in Wonderland» . Вызовите функцию и убедитесь в том, что название книги правильно пере- дается как аргумент при вызове функции . Передача аргументов Определение функции может иметь несколько параметров, и может оказаться, что при вызове функции должны передаваться несколько аргументов. Существуют несколько способов передачи аргументов функциям. Позиционные аргументы перечисляются в порядке, точно соответствующем порядку записи параметров; именованные аргументы состоят из имени переменной и значения; наконец, суще- ствуют списки и словари значений. Рассмотрим все эти способы. Позиционные аргументы При вызове функции каждому аргументу должен быть поставлен в соответствие параметр в определении функции. Проще всего сделать это на основании порядка перечисления аргументов. Значения, связываемые с аргументами подобным об- разом, называются позиционными аргументами. Чтобы понять, как работает эта схема, рассмотрим функцию для вывода информа- ции о домашних животных. Функция сообщает тип животного и его имя: pets.py def describe_pet(animal_type, pet_name): """Выводит информацию о животном.""" print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet('hamster', 'harry') 138 Глава 8 • Функции Из определения видно, что функции должен передаваться тип животного ( animal_type ) и его имя ( pet_name ). При вызове describe_pet() необходимо пере- дать тип и имя — именно в таком порядке. В этом примере аргумент 'hamster' сохраняется в параметре animal_type , а аргумент 'harry' сохраняется в параметре pet_name . В теле функции эти два параметра используются для вывода инфор- мации: I have a hamster. My hamster's name is Harry. Многократные вызовы функций Функция может вызываться в программе столько раз, сколько потребуется. Для вывода информации о другом животном достаточно одного вызова describe_pet() : def describe_pet(animal_type, pet_name): """Выводит информацию о животном.""" print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet('hamster', 'harry') describe_pet('dog', 'willie') Во втором вызове функции describe_pet() передаются аргументы 'dog' и 'willie' По аналогии с предыдущей парой аргументов Python сопоставляет аргумент 'dog' с параметром animal_type , а аргумент 'willie' с параметром pet_name Как и в предыдущем случае, функция выполняет свою задачу, но на этот раз вы- водятся другие значения: I have a hamster. My hamster's name is Harry. I have a dog. My dog's name is Willie. Многократный вызов функции — чрезвычайно эффективный способ работы. Код вывода информации о домашнем животном пишется один раз в функции. Каждый раз, когда вы захотите вывести информацию о новом животном, вы вызываете функцию с данными нового животного. Даже если код вывода информации раз- растется до 10 строк, вы все равно сможете вывести информацию всего одной командой — для этого достаточно снова вызвать функцию. Функция может иметь любое количество позиционных аргументов. При вызове функции Python перебирает аргументы, приведенные в вызове, и сопоставляет каждый аргумент с соответствующим параметром из определения функции. О важности порядка позиционных аргументов Если нарушить порядок следования аргументов в вызове при использовании по- зиционных аргументов, возможны неожиданные результаты: def describe_pet(animal_type, pet_name): """Выводит информацию о животном.""" Передача аргументов 139 print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet('harry', 'hamster') В этом вызове функции сначала передается имя, а потом тип животного. Так как аргумент 'harry' находится в первой позиции, значение сохраняется в параметре animal_type , а аргумент 'hamster' сохраняется в pet_name . На этот раз вывод полу- чается бессмысленным: I have a harry. My harry's name is Hamster. Если вы получили подобные странные результаты, проверьте, соответствует ли порядок следования аргументов в вызове функции порядку параметров в ее опре- делении. Именованные аргументы Именованный аргумент представляет собой пару «имя—значение», передаваемую функции. Имя и значение связываются с аргументом напрямую, так что при пере- даче аргумента путаница с порядком исключается. Именованные аргументы из- бавляют от хлопот с порядком аргументов при вызове функции, а также проясняют роль каждого значения в вызове функции. Перепишем программу pets .py с использованием именованных аргументов при вызове describe_pet() : def describe_pet(animal_type, pet_name): """Выводит информацию о животном.""" print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet(animal_type='hamster', pet_name='harry') Функция describe_pet() не изменилась. Однако на этот раз при вызове функ- ции мы явно сообщаем Python, с каким параметром должен быть связан каждый аргумент. При обработке вызова функции Python знает, что аргумент 'hamster' должен быть сохранен в параметре animal_type , а аргумент 'harry' в параметре pet_name Порядок следования именованных аргументов в данном случае не важен, потому что Python знает, где должно храниться каждое значение. Следующие два вызова функции эквивалентны: describe_pet(animal_type='hamster', pet_name='harry') describe_pet(pet_name='harry', animal_type='hamster') ПРИМЕЧАНИЕ При использовании именованных аргументов будьте внимательны — имена должны точно совпа- дать с именами параметров из определения функции . 140 Глава 8 • Функции Значения по умолчанию Для каждого параметра вашей функции можно определить значение по умолча- нию. Если при вызове функции передается аргумент, соответствующий данному параметру, Python использует значение аргумента, а если нет — использует зна- чение по умолчанию. Таким образом, если для параметра определено значение по умолчанию, вы можете опустить соответствующий аргумент, который обычно включается в вызов функции. Значения по умолчанию упрощают вызовы функций и проясняют типичные способы использования функций. Например, если вы заметили, что большинство вызовов describe_pet() исполь- зуется для описания собак, задайте animal_type значение по умолчанию 'dog' Теперь в любом вызове describe_pet() для собаки эту информацию можно опустить: def describe_pet(pet_name, animal_type='dog'): """Выводит информацию о животном.""" print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet(pet_name='willie') Мы изменили определение describe_pet() и включили для параметра animal_type значение по умолчанию 'dog' . Если теперь функция будет вызвана без указания animal_type , Python знает, что для этого параметра следует использовать значение 'dog' : I have a dog. My dog's name is Willie. Обратите внимание: в определении функции пришлось изменить порядок параме- тров. Так как благодаря значению по умолчанию указывать аргумент с типом жи- вотного не обязательно, единственным оставшимся аргументом в вызове функции остается имя домашнего животного. Python интерпретирует его как позиционный аргумент, и если функция вызывается только с именем животного, этот аргумент ставится в соответствие с первым параметром в определении функции. Именно по этой причине имя животного должно быть первым параметром. В простейшем варианте использования этой функции при вызове передается только имя собаки: describe_pet('willie') Вызов функции выводит тот же результат, что и в предыдущем примере. Един- ственный переданный аргумент 'willie' ставится в соответствие с первым па- раметром в определении, pet_name . Так как для animal_type аргумент не указан, Python использует значение по умолчанию 'dog' . Для вывода информации о лю- бом другом животном, кроме собаки, используется вызов функции следующего вида: describe_pet(pet_name='harry', animal_type='hamster') Так как аргумент для параметра animal_type задан явно, Python игнорирует зна- чение параметра по умолчанию. Передача аргументов 141 ПРИМЕЧАНИЕ Если вы используете значения по умолчанию, все параметры со значением по умолчанию должны следовать после параметров, у которых значений по умолчанию нет . Это необходимо для того, чтобы Python правильно интерпретировал позиционные аргументы . Эквивалентные вызовы функций Так как позиционные аргументы, именованные аргументы и значения по умол- чанию могут использоваться одновременно, часто существуют несколько эквива- лентных способов вызова функций. Возьмем оператор describe_pets() с одним значением по умолчанию: def describe_pet(pet_name, animal_type='dog'): При таком определении аргумент для параметра pet_name должен задаваться в лю- бом случае, но это значение может передаваться как в позиционном, так и в име- нованном формате. Если описываемое животное не является собакой, то аргумент animal_type тоже должен быть включен в вызов, и этот аргумент тоже может быть задан как в позиционном, так и в именованном формате. Все следующие вызовы являются допустимыми для данной функции: describe_pet('willie') describe_pet(pet_name='willie') describe_pet('harry', 'hamster') describe_pet(pet_name='harry', animal_type='hamster') describe_pet(animal_type='hamster', pet_name='harry') Все вызовы функции выдадут такой же результат, как и в предыдущих примерах. |