Занятие № 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() -
возвращает значение поляcourse
setCourse(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)
- добавить заказ к списку, который хранится в полеitems
getTotalPrice()
- возвращает общую стоимость всех товаров в корзине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