Занятие № 11. Описание типов пользователя
Цель: научиться создавать собственные классы и объекты.
Теория
Объекты и классы
Все значения в Python являются объектами определённых классов. Чтобы узнать экземпляром какого класса является значение, используем функцию type():
Даже функции являются объектами класса function:
Поэтому важно понимать, как можно создать собственный тип данных, если нет подходящего среди стандартных.
Описание класса
Создание собственного класса рассмотрим на примере описания собственного типа Point, который будет хранить информацию о точке не плоскости. Любой объект хранит в себе набор членов класса. К ним относятся поля - состояние объекта и методы - функции, которые меняют состояние класса.
Простейшее описание класса выглядит так:
Сейчас в классе Point нет ни полей ни методов.
Чтобы создать экземпляр класса или объект этого типа, необходимо записать имя класса с круглыми скобками:
Программа скажет нам, что переменная a ссылается на объект класса <class '__main__.Point'>.
Для обращения к полям и методам класса используется оператор . точка. Вы использовали подобную запись когда, например, добавляли элемент к списку, записывая инструкцию <список>.
.
Последовательно запускайте интерактивные примеры с кодом. Следующий фрагмент кода может зависеть от предыдущего.
Добавить поля к объекту можно также с помощью их записи через точку:
Методы класса
Каждый раз задавать значения для полей таким образом неудобно, поэтому объявим функцию init(), которая в качестве аргументов будет принимать объект типа Point и значения полей x и y:
Python позволяет поместить функцию инициализации полей класса внутрь описания класса. Для этого в класс добавляется метод __init__(). Первый параметр метода будет ссылкой на объект, который нужно инициализировать. Этот параметр может иметь произвольное имя, но принято называть его self:
Теперь при создании объекта класса можно указать начальные значения полей класса:
Посмотрите на последовательное выполнение кода, в котором создаётся объект класса Point.
После выполнения кода в строке
будет вызван метод __init__().
Опишем ещё одну функцию origin_dist() с помощью которой рассчитаем расстояние от начала координат до заданной точки:
Функцию origin_dist() так же можно оформить как метод класса Point. Как и в случае с __init__(), первый параметр любого метода класса - это ссылка на объект, который нужно обработать:
Посмотрите на последовательное выполнение кода в котором используется метод origin_dist() класса Point.
В записи вызова метода tochka.origin_dist() в скобках не указываются аргументы. Подобная запись преобразуется Python в следующий эквивалентный код:
Специальные методы класса
Когда мы используем функцию print() и выводим значение выражения того или иного типа, это значение преобразуется в строку. Если попробовать вывести объект класса Point, то получим следующий результат:
Результат не показывает содержимого полей класса. Чтобы определить, как преобразовать объект класса в строку, в его определении нужно добавить специальный метод __str__(). Добавим этот метод к объявлению класса Point, чтобы выводить координаты точки:
Специальные методы позволяют реализовать в собственном классе функции доступные для других типов объектов.
Примеры
Пример № 1 (ex01.py)
Опишите класс MSDice который реализует многогранную игральную кость. Описание класса содержит количество граней и текущее значение.
За пошаговым выполнением программы можно проследить, перейдя по следующей ссылке.
Задания для самостоятельной работы
Задание № 1 (sam01.py)
Опишите класс Robot, содержащий одно поле model и метод sayHi(name). Метод должен поприветствовать человека, чьё имя указано в параметре name.
Для написания программы используйте следующий шаблон. Вместо комментариев в методе __init__ и say_Hi напишите их реализацию.
Шаблон:
class Robot:
def __init__(self, model):
# сохраняем модель робота в поле с именем model
def sayHi(self, name):
# метод должен вывести сообщение
# Привет, <name>. Меня зовут <model>.
# следующий код оставьте без изменений
bender = Robot("Бендер")
bender.sayHi("Фрай")
term = Robot("T-800")
term.sayHi("Сара Конор")Пример:
Привет, Фрай. Меня зовут Бендер
Привет, Сара Конор. Меня зовут T-800
Задание № 2 (sam02.py)
Опишите класс Student. Класс должен содержать следующие поля:
last_name- фамилия студента (строка)course- номер курса, на котором студент учится (целое число)
Класс должен содержать следующие методы:
__init__(last_name, course)- конструктор, который создаёт объект и сохраняет нужные поляprintInfo()- выводит на экран информацию о студенте (см. пример)getCourse() -возвращает значение поляcoursesetCourse(new_course)- меняет текущий номер курса наnew_course
Для написания программы используйте следующий шаблон.
Шаблон:
# тут расположите описание класса Student
# следующий код оставьте без изменений
stud1 = Student("Иванов", 2)
stud1.printInfo()
print("Номер курса:", stud1.getCourse())
print("Переводим на следующий курс")
stud1.setCourse(3)
print("Номер курса:", stud1.getCourse())Пример:
Фамилия: Иванов; учится на 2 курсе
Номер курса: 2
Переводим на следующий курс
Номер курса: 3
Задание № 3 (sam03.py)
Создайте класс Player, описывающий игрока у которого есть следующие поля:
nickname- имя игрока (строка)exp_points- количество очков опыта (целое число); начальное значение - 0inventory- список предметов, которые есть у игрока (список); начальное значение - []
Класс должен содержать следующие методы:
__init__(nickname)- конструктор, принимающий в качестве параметра имя игрока. Также конструктор инициализирует поляexp_points=0иinventory=[]__str__- преобразование объекта в строку (формат вывода см. в примере)addExp(exp)- добавить игрокуexpочков опытаaddItem(item)- добавить к спискуinventoryпредметitem(строка)removeItem(item)- удалить из спискаinventoryпредмет с именемitem(строка)
Для написания программы используйте следующий шаблон.
Шаблон:
# тут расположите описание класса Player
# следующий код оставьте без изменений
novice = Player("MegaPro") # создание объекта
print(novice) # вывод информации об объекте (будет вызван метод __str__)
novice.addExp(100) # добавляем 100 очков опыта
novice.addItem("броня") # добавляем предмет к инвентарю
novice.addItem("меч") # добавляем предмет к инвентарю
print(novice) # вывод информации об объекте
novice.addExp(50) # добавляем 50 очков опыта
novice.removeItem("броня") # удаляем предмет из инвентаря
print(novice)Пример:
MegaPro - 0 exp. - []
MegaPro - 100 exp. - ['броня', 'меч']
MegaPro - 150 exp. - ['меч']
Задание № 4 (sam04.py)
С помощью ООП реализуйте модель корзины для магазина. Объект с товаром содержит его название и цену. Корзина содержит электронную почту заказчика и список товаров. Опишите два класса - Item (Товар) и Cart (Корзина).
Поля класса Item:
title- название товара (строка)price- цена товара (целое число)
Методы класса Item:
__init__(title, price)- конструктор классаgetPrice()- возвращает цену товара__str__() - Преобразование объекта в строку (формат вывода см. в примере)
Поля класса Cart:
email- электронная почта заказчика (строка)items- список товаров в корзине (список)
Методы класса Cart:
__init__(email)- конструктор класса; полеitemsинициализируется пустым списком []addItem(item)- добавить заказ к списку, который хранится в полеitemsgetTotalPrice()- возвращает общую стоимость всех товаров в корзинеprintOrder()- выводит на экран список всех товаров в корзине (формат вывода см. в примере)
Для написания программы используйте следующий шаблон.
Шаблон:
# тут расположите описание класса Item
# тут расположите описание класса Cart
# следующий код оставьте без изменений
apple = Item("Яблоко", 20) # создаём товар
pen = Item("Ручка", 10) # создаём товар
print(apple) # выводим информацию о товаре (будет вызван метод __str__)
print("Цена товара:", apple.getPrice()) # получаем цену товара
my_cart = Cart("user@mail.com") # создаём корзину
my_cart.addItem(apple) # добавляем первый товар в корзину
my_cart.addItem(pen) # добавляем второй товар в корзину
my_cart.printOrder() # выводит список товаров в корзине
print("Сумма:", my_cart.getTotalPrice()) # получаем общую стоимость заказаПример:
Яблоко - 20 руб.
Цена товара: 20
Товары в корзине:
Яблоко - 20 руб.
Ручка - 10 руб.
Сумма: 30