Класи та об’єкти Python: Підручник 2026
Більшість навчальних посібників з ООП Python навчають синтаксису та пропускають розумову модель. Цей робить протилежне — ви залишите чітке уявлення про те, що таке клас під час виконання, коли вдаватися до @dataclass замість написання __init__ вручну, і як self насправді працює (це не магія).
Ми розглянемо: мінімальний життєздатний клас із чотирьох рядків, чому self є параметром, клас проти атрибутів екземпляра (помилка №1 для початківців), шість методів dunder, які ви побачите скрізь, @dataclass як сучасний стандарт за замовчуванням і жорстке правило, коли залишати класи в спокої та використовувати звичайну функцію.
Ментальна модель: клас — це фабрика
Клас у Python — це фабрика, яка створює об’єкти. Щоразу, коли ви викликаєте Rect(3, 4), Python створює новий об’єкт із власним сховищем і повертає його вам.
Ось і вся механіка. Клас є планом; кожен виклик Rect(...) є штампом креслення в оновлену оперативну пам'ять.
self - це лише параметр
Плутанина №1 для людей, які працюють із JS або Ruby: self у Python є явним. Перший параметр кожного методу є посиланням на екземпляр, який викликається.
Отже, c.bump() є синтаксичним цукром для Counter.bump(c). Python передає екземпляр як перший аргумент. Ви можете назвати це me, this або foo — self є умовністю, а не ключовим словом. Дотримуйтесь self (PEP 8), щоб інші розробники Python могли прочитати ваш код.
Перехоплення атрибутів класу проти екземпляра
Найпоширеніша помилка ООП Python у кодовій базі для початківців:
items = [] в області класу створює ОДИН список, спільний для кожного екземпляра. a.add("milk") змінює його, тому b.items бачить той самий список.
Правило: ініціалізувати змінний стан у `__init__`, а не в області класу.
Ця помилка надсилалася у виробництво більше разів, ніж будь-який розробник Python визнає. Слідкуйте за списками, диктовками, наборами в області класу.
Шість методів, які ви побачите всюди
Методи Dunder (__name__) — це перевантаження операторів Python. Ці шість охоплюють 95% того, з чим ви зіткнетеся:
1. __init__(self, ...) — конструктор
Запускається під час створення об’єкта. Тут установіть атрибути екземпляра. Нічого не повертати (Python застосовує None).
2. __repr__(self) — рядок для розробника
Викликається print(x), якщо __str__ відсутній, і завжди REPL. Шукайте щось, що можна було б вставити назад у Python, щоб відтворити об’єкт:
3. __eq__(self, other) — рівність
Без нього Rect(3, 4) == Rect(3, 4) повертає False (за замовчуванням ідентичність). Порівняти поле за полем:
4. __hash__(self) — хешування
Якщо ви замінюєте __eq__, ви ПОВИННІ також перевизначати __hash__ або набори Python __hash__ = None (об'єкт стає нехешованим). Найпростіший: повернути хеш((self.width, self.height)).
5. __len__(self) — для len(obj)
Змушує len(cart) == 5 працювати.
6. __iter__(self) — для for x in obj:
Повернути ітератор. yield всередині робить клас повторюваним:
@dataclass — сучасне значення за умовчанням
Якщо ваш клас є переважно тримачем даних (три поля, __init__, __repr__, __eq__), припиніть писати цей шаблон. @dataclass генерує все це з ваших анотацій типу:
Згенеровано __init__, __repr__ і __eq__. Додайте @dataclass(frozen=True), щоб зробити об’єкт незмінним ТА отримати __hash__ безкоштовним.
Правило: спочатку досягніть @dataclass. Напишіть створений вручну клас лише тоді, коли вам потрібні методи, які не є засобами доступу до атрибутів.
__slots__ — оптимізація пам'яті (розширена)
За замовчуванням кожен екземпляр містить __dict__, тому ви можете додавати довільні атрибути. __slots__ заміни, які диктують для фіксованої структури C-рівня — менший обсяг ОЗУ та швидший доступ до атрибутів:
Використовуйте __slots__, коли: (a) ви створюєте мільйони екземплярів і маєте значення RAM, або (b) ви хочете виявити неправильне призначення атрибутів під час виконання. В іншому випадку пропустіть його — він вимикає pickle за замовчуванням і порушує множинне успадкування тонкими способами.
Коли залишати уроки наодинці
Жорстке правило: якщо у вашому класі є ОДИН метод плюс `__init__`, можливо, це має бути функція.
Класи отримують свою вагу, коли вони зберігають state у кількох викликах методів або коли вони реалізують чітко визначений протокол (__iter__, __enter__, __eq__ тощо). Одноразова логіка — це функція.
Спадщина — використовуйте її економно
Спадщина реальна, але використовується надмірно. У Python 2026 віддайте перевагу composition — утримуйте інший об’єкт як атрибут замість успадкування від нього:
Успадковуйте лише тоді, коли у вас є справжні стосунки "є-є" І ви хочете змінити поведінку. NamedRect, який успадковує Rect для додавання поля name, підходить. Побудова п’ятирівневої ієрархії успадкування для класу бізнес-логіки – це код, який ви розплутаєте за 6 місяців.
Класи є однією з найпотужніших функцій Python, і однією з найпростіших для надмірного використання. Ментальна модель, яка допомагає: клас — це фабрика для об’єктів, self — це звичайний параметр, змінний стан переходить у __init__, спочатку дотягніться до @dataclass і повертайтеся до функції щоразу, коли клас має менше двох методів передачі стану.
Наступний крок: 30 практичних уроків ООП, які охоплюють класи, @dataclass, успадкування проти композиції та методи dunder — зі справжнім Python, що працює у вашому браузері, і наставником ШІ на кожному кроці.