Python · Синтаксис · Початковий рівень
ООП: успадкування та dunder-методи
Завдання по ООП в Python на спадкування та спеціальні методи: дочірні класи, перевизначення поведінки, __str__, __len__, розширення базових класів та робота з об'єктною моделлю.
Короткий вступ до теми та пояснення перед вправами (вправи нижче):
Dunder-методи — __str__ і __len__
#Патерни успадкування і dunder-методів
#Швидкий довідник: наслідування та dunder-методи
#Вправи:
Animal і Dog через наслідування.
#class Animal:
pass
class Dog(Animal):
pass
Рішення
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __str__(self):
return f"Dog: {self.name}"
# Можна деталізувати:
class Dog(Animal):
def __str__(self):
return f"Dog: {self.name}"
def tell(self):
print("Bark!!!") # "Гав" англійською. Собакам теж потрібен перекладач..
class Cat(Animal):
def __str__(self):
return f"Cat: {self.name}"
def tell(self):
print("Cats don't care about human commands!")
# self все одно потрібно прийняти, навіть якщо в методі не використовується.
Book із рядковим представленням.
#class Book:
pass
Рішення
class Book:
def __init__(self, title, pages):
self.title = title
self.pages = pages
def __len__(self):
return self.pages
def __str__(self):
return f"Book: {self.title} ({self.pages} pages)"
User і Admin.
#class User:
pass
class Admin(User):
pass
Рішення
class User:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
class Admin(User):
def __str__(self):
return f"Admin: {self.name}"
Коробка з предметами.
#class Box:
pass
Рішення
class Box:
def __init__(self, items_count):
self.items_count = items_count
def add(self, count=1):
self.items_count += count
def remove(self, count=1):
self.items_count -= count
def __len__(self):
return self.items_count
# Зі списком складніше і по-іншому:
class Box:
def __init__(self):
self.items = []
self.items_count = len(self.items)
def add(self, item):
self.items.append(item)
self.items_count = len(self.items)
def remove(self, item):
if item in self.items:
self.items.remove(item)
self.items_count = len(self.items)
else:
print("Кіт із коробки каже: Такого тут немає, до побачення!")
def __len__(self):
return self.items_count
Message зі spam-прапором.
#class Message:
pass
Рішення
class Message:
def __init__(self, text):
self.text = text
self.spam = None
self.spam_triggers = ["куплю", "дорого"] # Так, я про це не говорив,
# але й не забороняв.
def is_spam(self):
if self.spam is not None: # пояснення нижче, тут я вже "перегнув"
return self.spam
for trigger in self.spam_triggers:
if trigger in self.text:
self.spam = True
return True
self.spam = False
return False
def __len__(self):
return len(self.text)
# Наявність self.spam після першого виклику is_spam дозволить при повторних перевірках
# не запускати механізм перевірки, а просто подивитися в УЖЕ ОБЧИСЛЕНИЙ атрибут (оптимізація).
m = Message("Куплю старые телевизоры дорого!!!")
if m.is_spam(): # виконується реальна перевірка
...
if m.is_spam(): # вже буде взято із self.spam
...
Employee і Manager.
#class Employee:
pass
class Manager(Employee):
pass
Рішення
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
def change_salary(self, coef): # наприклад коефіцієнт 1.1 - збільшити на 10%
self.salary = round(self.salary * coef) # без другого аргументу округлить до цілого
class Manager(Employee):
def __str__(self):
return f"Manager {self.name} earns {self.salary}"
chel = Manager("Bob", 1000)
chel.change_salary(1.1)
print(chel) # Manager Bob earns 1100
Playlist і CustomPlaylist.
#class Playlist:
pass
Рішення
class Playlist:
def __init__(self, songs): # 1 аргумент - список із треками
self.songs = songs
def add(self, song):
if song not in self.songs:
self.songs.append(song)
def remove(self, song):
if song in self.songs:
self.songs.remove(song)
def reverse(self):
self.songs.reverse()
def __len__(self):
return len(self.songs)
def __bool__(self):
return bool(self.songs)
# або
# class Playlist:
# def __init__(self, *songs): # треки як окремі аргументи
# self.songs = list(songs) # просто вирішив нагадати про *args
# # решта така сама.
class CustomPlaylist(Playlist):
def add(self, song):
self.songs.append(song)
Іменований CustomPlaylist.
#class CustomPlaylist(Playlist):
def __init__???
???
def add(self, song):
self.songs.append(song)
Рішення
class CustomPlaylist(Playlist):
def __init__(self, songs, name):
super().__init__(songs)
self.name = name
def add(self, song):
self.songs.append(song)
def __str__(self):
return f"Playlist: {self.name}"
MagicBox із випадковим предметом.
#from random import choice # функція випадкового вибору з послідовності
class Box:
def __init__(self):
self.items = []
self.items_count = len(self.items)
def add(self, item):
self.items.append(item)
self.items_count = len(self.items)
def remove(self, item):
if item in self.items:
self.items.remove(item)
self.items_count = len(self.items)
else:
print("Кот из коробки говорит: Такого тут нет, досвидания!")
def __len__(self):
return self.items_count
things = ["Шапка", "Зонтик", "Кружка"]
class MagicBox(Box):
def __init__(self):
...
Рішення
from random import choice # функція випадкового вибору з послідовності
class Box:
def __init__(self):
self.items = []
self.items_count = len(self.items)
def add(self, item):
self.items.append(item)
self.items_count = len(self.items)
def remove(self, item):
if item in self.items:
self.items.remove(item)
self.items_count = len(self.items)
else:
print("Кот из коробки говорит: Такого тут нет, досвидания!")
def __len__(self):
return self.items_count
things = ["Шапка", "Зонтик", "Кружка"]
class MagicBox(Box):
def __init__(self):
super().__init__()
self.items.append(choice(things))
self.items_count = len(self.items)
# АБО:
class MagicBox(Box):
def __init__(self):
super().__init__()
self.add(choice(things)) # так крутіше
x = MagicBox()
print(x.items)