Відео пояснює базові елементи Python ООП на прикладах Page Object і компонентів: навіщо методам потрібен `self`, яку залежність передають через `__init__`, що зберігає Playwright `page`, яку роль має `__init__.py` та як у Python позначають non-public API. Завершується розбором інкапсуляції як керованого публічного інтерфейсу, а не просто «приховування коду».
Примітка: конспект укладено за автоматичними українськими субтитрами; технічні терміни нормалізовано, а пояснення `__init__`, package і name mangling уточнено відповідно до поведінки Python.
Після цього уроку ви зможете
Пояснити різницю між local name та instance attribute через self.
Передавати Page Object обов’язковий стан через __init__.
Відрізняти non-public convention, name mangling і справжній security boundary.
Пояснити роль __init__.py та виняток implicit namespace packages.
self — явний параметр instance method, через який код звертається до конкретного екземпляра класу. self.card означає атрибут цього екземпляра, тоді як локальна змінна card живе лише у своїй функції або блоці видимості.
Однакові назви технічно можливі, але збільшують когнітивне навантаження. Префікс self. одночасно потрібен Python для правильного доступу до instance attribute і показує читачеві, де зберігається стан.
Термін
self
Загальноприйнята назва першого параметра instance method. Python передає bound instance неявно під час виклику obj.method(), але ім’я self саме по собі не є keyword.
Практика
Відокремити local state від instance state
Створи два PageObject instances із різними page values і доведи assertions, що зміна local variable не змінює self.page іншого instance.
Обидва instances мають незалежні page attributes.
У method немає global state.
Автор може пояснити, чому obj.method() передає obj як перший argument.
Через __init__ клас отримує залежності й початковий стан, без яких його методи не мають сенсу. Наприклад, компонент приймає кореневий locator, а Page Object — Playwright page; наступні методи перевикористовують ці значення через self.
У повсякденній мові __init__ часто називають constructor. Технічно екземпляр створює __new__, а __init__ ініціалізує вже створений об’єкт. Для звичайного Page Object достатньо реалізувати саме __init__.
Уточнення
__init__ — initializer, не етап створення instance
У повсякденній мові __init__ часто називають constructor, але Python data model розділяє __new__, який створює instance, і __init__, який налаштовує вже створений instance.
Термін
__init__
Initializer, який викликається після створення instance методом __new__ і налаштовує його початковий стан; він не повинен повертати значення, відмінне від None.
Playwright Page представляє окрему вкладку або сторінку в browser context. Переданий у Page Object екземпляр визначає, з яким саме браузерним контекстом працюватимуть locators, переходи й assertions.
Збереження page як self.page прибирає потребу передавати його в кожен метод. Залежність залишається явною в initializer, а всі дії конкретного Page Object використовують одну й ту саму вкладку.
Наявність __init__.py робить директорію звичайним Python package і може визначати його зручний публічний API через imports або __all__. Це допомагає IDE, імпортам і читачеві зрозуміти межу модуля.
Сучасний Python також підтримує namespace packages без __init__.py, тому файл не є абсолютною вимогою для кожної імпортованої директорії. У навчальному проєкті явний package зазвичай простіший і передбачуваніший.
Що змінилося після запису
__init__.py не є абсолютною вимогою
У відеоУ відео __init__.py пояснено як ознаку Python package і місце для публічних imports.
АктуальноДля regular package це коректна практична модель, але Python 3.3+ підтримує implicit namespace packages, де namespace directory навмисно не містить __init__.py.
Перевірено 2026-07-31
Термін
namespace package
Package, який може бути розподілений між кількома distributions. Native namespace packages доступні з Python 3.3 і не мають __init__.py у namespace directory.
Один underscore, наприклад _locator, — домовленість «внутрішня деталь, не використовуй без потреби». Інтерпретатор не забороняє доступ. Подвійний початковий underscore запускає name mangling, щоб зменшити випадкові конфлікти в нащадках, але теж не створює security boundary.
На відміну від private або protected у статично типізованих мовах, Python більше покладається на дисципліну автора й користувача класу. IDE може попередити про звернення до non-public member, але виконання зазвичай можливе.
Термін
non-public API
Python convention: name з одним leading underscore вважається implementation detail. Подвійний leading underscore запускає name mangling для уникнення конфліктів, але не гарантує privacy.
Внутрішня функція корисна, коли складна бізнес-дія складається з кількох неочевидних технічних кроків або коли розрахунок потребує предметної назви. Вона зменшує деталі у публічному методі й показує, що не є частиною API класу.
Водночас Page Object має залишатися простим. Не варто ділити кожен рядок на helper: виділення виправдане, коли воно називає реальну дію або приховує поточну складність.
Інкапсуляція поєднує стан і поведінку та визначає дозволений спосіб взаємодії з об’єктом. Практичний акцент — не «сховати все», а відкрити невеликий зрозумілий інтерфейс, який не змушує зовнішній код знати внутрішню послідовність дій.
Користувач класу працює за правилами його публічних методів. Це знижує coupling: внутрішню реалізацію можна змінити, поки зовнішній контракт залишається стабільним.
Java і C# формально перевіряють public, private та protected, тоді як Python використовує переважно conventions. Водночас суворіші мови скорочують boilerplate, а Python і JavaScript додають type hints та інструменти статичного аналізу.
Python annotations допомагають IDE й type checker, але самі по собі не перетворюють Python на статично типізовану мову та не гарантують runtime-перевірку. Їхня користь — ранній зворотний зв’язок і краща навігація по API.
Абстрактні принципи стають зрозумілішими після практики: спочатку помітити code smells, потім розібрати базові механізми ООП, далі — patterns і SOLID. KISS, DRY та YAGNI варто застосовувати паралельно як питання до конкретного коду, а не як привід будувати структуру наперед.
Найкраща перевірка розуміння — пояснити, який публічний контракт має клас, який стан йому справді потрібен і яку поточну проблему вирішує кожен виділений метод.
Орієнтир для завершення домашніх робіт — кінець або середина березня залежно від фактичного темпу групи. Термін може коригуватися, якщо окрема практика стабільно потребує більше часу, ніж очікувалося.