У цій статті є фрагмент, що показує використання __bases__
для динамічної зміни ієрархії успадкування деякого коду Python, додаючи клас до існуючої колекції класів, з яких він успадковує. Добре, це важко прочитати, код, мабуть, зрозуміліший:
class Friendly:
def hello(self):
print 'Hello'
class Person: pass
p = Person()
Person.__bases__ = (Friendly,)
p.hello() # prints "Hello"
Тобто, Person
не успадковує з Friendly
на рівні джерела, а це відношення успадкування додається динамічно під час виконання шляхом модифікації __bases__
атрибута класу Person. Однак, якщо ви зміните Friendly
та Person
станете новими класами стилів (шляхом успадкування від об'єкта), ви отримаєте таку помилку:
TypeError: __bases__ assignment: 'Friendly' deallocator differs from 'object'
Трохи погуглити, здається, вказує на деякі несумісності між класами нового стилю та старого стилю щодо зміни ієрархії успадкування під час виконання. Зокрема: "Об'єкти класу нового стилю не підтримують присвоєння їх атрибуту бази " .
Моє запитання, чи можна змусити описаний вище приклад Friendly / Person працювати за допомогою класів нового стилю в Python 2.7+, можливо, за допомогою __mro__
атрибута?
Застереження: Я повністю усвідомлюю, що це незрозумілий код. Я цілком усвідомлюю, що в реальних виробничих кодах такі трюки, як правило, межують з нечитабельними, це суто продуманий експеримент, і для веселощів дізнатися щось про те, як Python вирішує проблеми, пов'язані з множинним успадкуванням.