Главная страница

Книга Изучаем Python


Скачать 4.68 Mb.
НазваниеКнига Изучаем Python
Дата10.12.2022
Размер4.68 Mb.
Формат файлаpdf
Имя файлаErik_Metiz_Izuchaem_Python_Programmirovanie_igr_vizualizatsia_da.pdf
ТипКнига
#837531
страница19 из 53
1   ...   15   16   17   18   19   20   21   22   ...   53
158 Глава 8 • Функции
Стилевое оформление функций
В стилевом оформлении функций необходимо учитывать некоторые подробности.
Функции должны иметь содержательные имена, состоящие из букв нижнего реги- стра и символов подчеркивания. Содержательные имена помогают вам и другим разработчикам понять, что же делает ваш код. Эти соглашения следует соблюдать и в именах модулей.
Каждая функция должна быть снабжена комментарием, который кратко поясняет, что же делает эта функция. Комментарий должен следовать сразу же за определе- нием функции в формате строк документации. Если функция хорошо документи- рована, другие разработчики смогут использовать ее, прочитав только описание.
Конечно, для этого они должны доверять тому, что код работает в соответствии с описанием, — но, если знать имя функции, какие аргументы ей нужны и какое значение она возвращает, они смогут использовать ее в своих программах.
Если для параметра задается значение по умолчанию, слева и справа от знака ра- венства не должно быть пробелов:
def имя_функции(параметр_0, параметр_1='значение_по_умолчанию')
Те же соглашения должны применяться для именованных аргументов в вызовах функций:
имя_функции(значение_0, параметр_1='значение')
Документ PEP 8 (https://www.python.org/dev/peps/pep-0008/) рекомендует ограни- чить длину строк кода 79 символами, чтобы строки были полностью видны в окне редактора нормального размера. Если из-за параметров длина определения функ- ции превышает 79 символов, нажмите Enter после открывающей круглой скобки в строке определения. В следующей строке дважды нажмите Tab, чтобы отделить список аргументов от тела функции, которое должно быть снабжено отступом только на один уровень.
Многие редакторы автоматически выравнивают дополнительные строки параме- тров по отступам, установленным в первой строке:
def имя_функции(
параметр_0, параметр_1, параметр_2,
параметр_3, параметр_4, параметр_5):
тело функции...
Если программа или модуль состоит из нескольких функций, эти функции можно разделить двумя пустыми строками. Так вам будет проще увидеть, где кончается одна функция и начинается другая.
Все команды import следует записывать в начале файла. У этого правила есть только одно исключение: файл может начинаться с комментариев, описывающих программу в целом.
УПРАЖНЕНИЯ
8-15 . Печать моделей: выделите функции примера print_models .py в отдельный файл с име- нем printing_functions .py . Разместите команду import в начале файла print_models .py и из- мените файл так, чтобы в нем использовались импортированные функции .

Итоги 159
8-16 . Импортирование: возьмите за основу одну из написанных вами программ с одной функцией . Сохраните эту функцию в отдельном файле . Импортируйте функцию в файл основной программы и вызовите функцию каждым из следующих способов:
import имя_модуля from имя_модуля import имя_функции from имя_модуля import имя_функции as псевдоним import имя_модуля as псевдоним from имя_модуля import *
8-17 . Стилевое оформление функций: выберите любые три программы, написанные для этой главы . Убедитесь в том, что в них соблюдаются рекомендации стилевого оформления, представленные в этом разделе .
Итоги
В этой главе вы научились писать функции и передавать аргументы, в которых функциям сообщается информация, необходимая для их работы. Вы узнали, как использовать позиционные и именованные аргументы и как передать функции про- извольное количество аргументов. Вы видели функции, которые выводят данные, и функции, которые возвращают значения. Вы научились использовать функции со списками, словарями, командами if и циклами while
. Также вы научились со- хранять функции в отдельных файлах, называемых модулями, чтобы код ваших программ стал проще и понятнее. Глава завершается рекомендациями по стилевому оформлению функций, чтобы ваши программы были хорошо структурированы и легко читались вами и другими разработчиками.
Каждый программист должен стремиться к написанию простого кода, который справ- ляется с поставленной задачей, и функции помогают вам в этом. Вы сможете писать блоки кода и оставлять их на будущее. Когда вы знаете, что функция правильно справ- ляется со своей задачей, считайте, что она работает, и переходите к следующей задаче.
В программе с использованием функций единожды написанный код может заново использоваться столько раз, сколько потребуется. Чтобы выполнить код, содержа- щийся в функции, достаточно написать всего одну строку с вызовом, а функция сделает все остальное. Если же потребуется модифицировать поведение функции, достаточно внести изменения всего в одном месте; они вступят в силу повсюду, где вызывается эта функция.
С функциями ваши программы проще читаются, а хорошо выбранные имена функций описывают, что делает та или иная часть программы. Прочитав серию вызовов функций, вы гораздо быстрее поймете, что делает функция, чем при чтении длинной серии программных блоков.
Функции также упрощают тестирование и отладку кода. Когда основная работа про- граммы выполняется набором функций, каждая из которых решает одну конкретную задачу, вам будет намного проще организовать тестирование и сопровождение вашего кода. Напишите отдельную программу, которая вызывает каждую функцию и про- веряет ее работоспособность во всех типичных ситуациях. В этом случае вы можете быть уверены в том, что ваши функции всегда работают правильно.
В главе 9 вы научитесь писать классы. Классы объединяют функции и данные в один удобный пакет, с которым вы можете работать гибко и эффективно.

9
Классы
Объектно-ориентированное программирование по праву считается одной из самых эффективных методологий создания программных продуктов. В объ- ектно-ориентированном программировании вы пишете классы, описывающие реально существующие предметы и ситуации, а затем создаете объекты на основе этих описаний. При написании класса определяется общее поведение для целой категории объектов.
Когда вы создаете конкретные объекты на базе этих классов, каждый объект автоматически наделяется общим поведением; после этого вы можете наделить каждый объект уникальными особенностями на свой выбор. Просто невероятно, насколько хорошо реальные ситуации моделируются в объектно-ориентированном программировании.
Создание объекта на основе класса называется созданием экземпляра; таким об- разом, вы работаете с экземплярами класса. В этой главе вы будете писать классы и создавать экземпляры этих классов. Вы укажете, какая информация может храниться в экземплярах, и определите действия, которые могут выполняться с экземплярами.
Также вы будете писать классы, расширяющие функциональность существу- ющих классов; это позволяет организовать эффективное совместное использо- вание кода похожими классами. Вы будете сохранять классы в модулях и импор- тировать классы, написанные другими программистами, в ваши программные файлы.
С хорошим пониманием объектно-ориентированного программирования вы взгля- нете на мир с точки зрения программиста. Вам будет проще понять свой код — увидеть не только то, что происходит в каждой его строке, но и более масштабные концепции, лежащие в его основе. Логика, заложенная в основу классов, научит вас мыслить последовательно, чтобы ваши программы эффективно решали прак- тически любые задачи, с которыми вы можете столкнуться.
Кроме того, классы упрощают жизнь вам и другим программистам, с которыми вам придется работать совместно над более серьезными проектами. Когда вы и другие программисты пишете код, базирующийся на сходной логике, вам проще понять код друг друга. Ваши программы будут понятны коллегам, и в результате все вы сможете добиться лучших результатов.

Создание и использование класса 161
Создание и использование класса
Классы позволяют моделировать практически все что угодно. Начнем с написания простого класса
Dog
, представляющего собаку — не какую-то конкретную, а собаку вообще. Что мы знаем о собаках? У них есть кличка и возраст. Также известно, что большинство собак умеют садиться и перекатываться по команде. Эти два вида информации (кличка и возраст) и два вида поведения (сидеть и перекатываться) будут включены в класс
Dog
, потому что они являются общими для большинства собак. Класс сообщает Python, как создать объект, представляющий собаку. По- сле того как класс будет написан, мы используем его для создания экземпляров, каждый из которых представляет одну конкретную собаку.
Создание класса Dog
В каждом экземпляре, созданном на основе класса
Dog
, будет храниться кличка и возраст; кроме того, в нем будут присутствовать методы sit()
и roll_over()
:
dog.py
 class Dog():

"""Простая модель собаки."""
 def __init__(self, name, age):
"""Инициализирует атрибуты name и age."""
 self.name = name self.age = age
 def sit(self):
"""Собака садится по команде."""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""Собака перекатывается по команде."""
print(self.name.title() + " rolled over!")
В этом коде есть много мест, заслуживающих вашего внимания, но не беспокойтесь.
Эта структура неоднократно встретится вам в этой главе, и вы еще успеете к ней привыкнуть. В точке  определяется класс с именем
Dog
. По общепринятым согла- шениям имена, начинающиеся с символа верхнего регистра, в Python обозначают классы. Круглые скобки в определении класса пусты, потому что класс создается с нуля. В точке  приведена строка документации с кратким описанием класса.
Метод __init__()
Функция, являющаяся частью класса, называется методом. Все, что вы узнали ранее о функциях, также относится и к методам; единственное практическое раз- личие — способ вызова методов. Метод
__init__()
в точке  — специальный метод, который автоматически выполняется при создании каждого нового экземпляра на базе класса
Dog
. Имя метода начинается и заканчивается двумя символами подчеркивания; эта схема предотвращает конфликты имен стандартных методов
Python и методов ваших классов.

162 Глава 9 • Классы
Метод
__init__()
определяется с тремя параметрами: self
, name и age
. Пара- метр self обязателен в определении метода; он должен предшествовать всем остальным параметрам. Он должен быть включен в определение для того, чтобы при будущем вызове метода
__init__()
(для создания экземпляра
Dog
) автомати- чески передавался аргумент self
. При каждом вызове метода, связанного с клас- сом, автоматически передается self
— ссылка на экземпляр; она предоставляет конкретному экземпляру доступ к атрибутам и методам класса. Когда вы создаете экземпляр
Dog
, Python вызывает метод
__init__()
из класса
Dog
. Мы передаем
Dog()
кличку и возраст в аргументах; значение self передается автоматически, так что его передавать не нужно. Каждый раз, когда вы захотите создать экземпляр на основе класса
Dog
, необходимо предоставить значения только двух последних аргументов name и age
Каждая из двух переменных, определяемых в точке , имеет префикс self
. Лю- бая переменная с префиксом self доступна для каждого метода в классе, и вы также сможете обращаться к этим переменным в каждом экземпляре, созданном на основе класса. Конструкция self.name
=
name берет значение, хранящееся в параметре name
, и сохраняет его в переменной name
, которая затем связыва- ется с создаваемым экземпляром. Процесс также повторяется с self.age
=
age
Переменные, к которым вы обращаетесь через экземпляры, тоже называются атрибутами.
В классе
Dog также определяются два метода: sit()
и roll_over()
. Так как этим методам не нужна дополнительная информация (кличка или возраст), они определяются с единственным параметром self
. Экземпляры, которые будут созданы позднее, смогут вызывать эти методы. Пока методы sit()
и roll_over()
ограничиваются простым выводом сообщения о том, что собака садится или перекатывается. Тем не менее концепцию легко расширить для практического применения: если бы этот класс был частью компьютерной игры, то эти методы вполне могли бы содержать код для создания анимации садящейся или пере- катывающейся собаки. А если бы класс был написан для управления роботом, то методы могли бы управлять механизмами, заставляющими робота-собаку выполнить соответствующую команду.
Создание классов в Python 2 .7
При создании классов в Python 2.7 необходимо внести одно незначительное из- менение — заключить в круглые скобки ключевое слово object
:
class ClassName(object):
В этом случае поведение классов Python 2.7 будет приближено к поведению клас- сов Python 3, что упрощает вашу работу в целом.
Скажем, в Python 2.7 класс
Dog будет определяться следующим образом:
class Dog(object):

Создание и использование класса 163
Создание экземпляра класса
Считайте, что класс — это своего рода инструкция по созданию экземпляров. Со- ответственно, класс
Dog
— инструкция по созданию экземпляров, представляющих конкретных собак.
Создадим экземпляр, представляющий конкретную собаку:
class Dog():
 my_dog = Dog('willie', 6)
 print("My dog's name is " + my_dog.name.title() + ".")
 print("My dog is " + str(my_dog.age) + " years old.")
Использованный в данном случае класс
Dog был написан в предыдущем при- мере. В точке  мы приказываем Python создать экземпляр собаки с кличкой 'willie'
и возрастом 6. В процессе обработки этой строки Python вызывает ме- тод
__init__()
класса
Dog с аргументами 'willie'
и 6. Метод
__init__()
создает экземпляр, представляющий конкретную собаку, и присваивает его атрибутам name и age переданные значения. Метод
__init__()
не содержит явной команды return
, но Python автоматически возвращает экземпляр, представляющий собаку. Этот экземпляр сохраняется в переменной my_dog
. Здесь нелишне вспомнить соглаше- ния по записи имен: обычно считается, что имя, начинающееся с символа верхнего регистра (например,
Dog
), обозначает класс, а имя, записанное в нижнем регистре
(например, my_dog
), обозначает отдельный экземпляр, созданный на базе класса.
Обращение к атрибутам
Для обращения к атрибутам экземпляра используется «точечная» запись. В стро- ке  мы обращаемся к значению атрибута name экземпляра my_dog
:
my_dog.name
Точечная запись часто используется в Python. Этот синтаксис показывает, как
Python ищет значения атрибутов. В данном случае Python обращается к экзем- пляру my_dog и ищет атрибут name
, связанный с экземпляром my_dog
. Это тот же атрибут, который обозначался self.name в классе
Dog
. В точке  тот же прием ис- пользуется для работы с атрибутом age
. В первой команде print вызов my_dog.name.
title()
записывает 'willie'
(значение атрибута name экземпляра my_dog
) с символа верхнего регистра. Во второй команде print вызов str(my_dog.age)
преобразует 6, значение атрибута age экземпляра my_dog
, в строку.
Пример выводит сводку известных фактов о my_dog
:
My dog's name is Willie.
My dog is 6 years old.
Вызов методов
После создания экземпляра на основе класса
Dog можно применять точечную за- пись для вызова любых методов, определенных в
Dog
:

164 Глава 9 • Классы class Dog():
my_dog = Dog('willie', 6)
my_dog.sit()
my_dog.roll_over()
Чтобы вызвать метод, укажите экземпляр (в данном случае my_dog
) и вызываемый метод, разделив их точкой. В ходе обработки my_dog.sit()
Python ищет метод sit()
в классе
Dog и выполняет его код. Строка my_dog.roll_over()
интерпретируется аналогичным образом.
Теперь экземпляр послушно выполняет полученные команды:
Willie is now sitting.
Willie rolled over!
Это очень полезный синтаксис. Если атрибутам и методам были присвоены содер- жательные имена (например, name
, age
, sit()
и roll_over()
), разработчик сможет легко понять, что делает блок кода, — даже если он видит этот блок впервые.
Создание нескольких экземпляров
На основе класса можно создать столько экземпляров, сколько вам потребуется.
Создадим второй экземпляр
Dog с именем your_dog
:
class Dog():
my_dog = Dog('willie', 6)
your_dog = Dog('lucy', 3)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
my_dog.sit()
print("\nYour dog's name is " + your_dog.name.title() + ".")
print("Your dog is " + str(your_dog.age) + " years old.")
your_dog.sit()
В этом примере создаются два экземпляра с именами
Willie и
Lucy
. Каждый экзем- пляр обладает своим набором атрибутов и способен выполнять действия из общего набора:
My dog's name is Willie.
My dog is 6 years old.
Willie is now sitting.
Your dog's name is Lucy.
Your dog is 3 years old.
Lucy is now sitting.
Даже если второй собаке будут назначены те же имя и возраст, Python все равно создаст отдельный экземпляр класса
Dog
. Вы можете создать сколько угодно экземпляров одного класса при условии, что эти экземпляры хранятся

Работа с классами и экземплярами 165
в переменных с разными именами или занимают разные позиции в списке или словаре:
УПРАЖНЕНИЯ
9-1 . Ресторан: создайте класс с именем Restaurant . Метод __init__() класса Restaurant дол- жен содержать два атрибута: restaurant_name и cuisine_type . Создайте метод describe_
restaurant(), который выводит два атрибута, и метод open_restaurant(), который выводит сообщение о том, что ресторан открыт .
Создайте на основе своего класса экземпляр с именем restaurant . Выведите два атрибута по отдельности, затем вызовите оба метода .
9-2 . Три ресторана: начните с класса из упражнения 9-1 . Создайте три разных экземпляра, вызовите для каждого экземпляра метод describe_restaurant() .
9-3 . Пользователи: создайте класс с именем User . Создайте два атрибута first_name и last_
name, а затем еще несколько атрибутов, которые обычно хранятся в профиле пользова- теля . Напишите метод describe_user(), который выводит сводку с информацией о пользо- вателе . Создайте еще один метод greet_user() для вывода персонального приветствия для пользователя .
Создайте несколько экземпляров, представляющих разных пользователей . Вызовите оба метода для каждого пользователя .
Работа с классами и экземплярами
Классы могут использоваться для моделирования многих реальных ситуаций. По- сле того как класс будет написан, разработчик проводит бульшую часть времени за работой с экземплярами, созданными на основе этого класса. Одной из первых задач станет изменение атрибутов, связанных с конкретным экземпляром. Атрибу- ты экземпляра можно изменять напрямую или же написать методы, изменяющие атрибуты по особым правилам.
Класс Car
Напишем класс, представляющий автомобиль. Этот класс будет содержать инфор- мацию о типе машины, а также метод для вывода краткого описания:
car.py
class Car():
"""Простая модель автомобиля."""
 def __init__(self, make, model, year):
"""Инициализирует атрибуты описания автомобиля."""
self.make = make self.model = model self.year = year
 def get_descriptive_name(self):
"""Возвращает аккуратно отформатированное описание."""
long_name = str(self.year) + ' ' + self.make + ' ' + self.model return long_name.title()
 my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())

1   ...   15   16   17   18   19   20   21   22   ...   53


написать администратору сайта