У ланцюжку Аудіокнига(Книга) → Книга(Видання) метод «опис» визначено у Видання і в Книга, але не в Аудіокнига. Що поверне аудіокнига.опис()?
__mro__ зліва направо: Аудіокнига → Книга → Видання → object, і перший знайдений виграє. Аудіокнига нічого не робить — вона просто не заважає пошуку йти далі. AttributeError буває лише тоді, коли методу немає ніде, включно з object.Похідний клас має власний __init__, у якому забули викликати super().__init__(...). Коли програма впаде?
AttributeError, і traceback покаже рядок усередині базового методу, а не місце справжньої помилки. Атрибути не «успадковуються»: вони зʼявляються тоді, коли якийсь __init__ їх запише.Ромб: class БФП(Сканер, Принтер), Сканер(Пристрій), Принтер(Пристрій), і кожен метод «запустити» друкує своє імʼя й кличе super().запустити(). Скільки рядків надрукується?
super() проходить його рівно один раз. Варіант із двома «Пристроями» — це те, що виходить при прямих викликах Сканер.запустити(self) і Принтер.запустити(self): обидва доходять до спільного предка окремо. Порядок цілком передбачуваний і задається порядком класів у дужках.У тілі Сканер.запустити написано super().запустити(). Метод викликали на обʼєкті класу БФП(Сканер, Принтер). Куди потрапить цей super()?
super() означає «наступний у MRO класу обʼєкта», а не «мій батько», — і Принтер не є базовим для Сканера взагалі. Саме завдяки цьому спільний предок у ромбі виконується один раз. Відповідь «у Пристрій» правильна лише для обʼєкта самого класу Сканер, де MRO інший.Каталог має три незалежні виміри: носій (3 варіанти), мова (2) і оправа (2). У скільки нових класів обійдеться додати четвертий носій?
Функція друкує каталог, викликаючи x.опис(). У каталозі є НастільнаГра — вона не походить від Видання, але метод «опис» у неї є. Що зміниться, якщо додати перевірку if isinstance(x, Видання)?
isinstance питає «якого ти роду», а функції потрібне вміння — і гра вміє рівно те, що треба. Надійності перевірка не додає: успадкувати Видання й не написати опис ніхто не заважає. Якщо тиха перевірка справді потрібна, питай про вміння прямо — hasattr(x, "опис").Похідний клас перевизначив метод «опис» і склав рядок сам, без super(). Що станеться з ним, коли формат опису зміниться в базовому класі?
super() метод похідного класу не звертається до базового ніяк, тож базовий код просто перестає виконуватись — і будь-яка зміна в ньому проходить повз. Це і є різниця між заміною й розширенням: варіант із super() отримує зміну задарма. Жодних попереджень Python тут не дає — перевизначення для нього цілком законне.Базовий клас успадковує ABC і має метод, позначений @abstractmethod. Нащадок цей метод не реалізував. Коли Python поскаржиться?
Афіша(...), а не десь потім. Варіант із AttributeError на виклику — це поведінка без abc, і вся цінність abc саме в тому, що помилка переїжджає на два кроки раніше, ближче до причини.