В этой статье есть фрагмент, показывающий использование __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'
Немного поиска в Google по этому вопросу кажется указывают на некоторую несовместимость между классами нового и старого стиля в отношении изменения иерархии наследования во время выполнения. В частности: «Объекты класса нового стиля не поддерживают присвоение их атрибуту bases».
Мой вопрос: можно ли заставить приведенный выше пример Friendly/Person работать, используя классы нового стиля в Python 2.7+, возможно, с помощью атрибута __mro__
?
Отказ от ответственности: я полностью понимаю, что это неясный код. Я полностью понимаю, что в реальном производственном коде подобные трюки, как правило, граничат с нечитаемостью, это чисто мысленный эксперимент, и для фанзиков нужно узнать что-то о том, как Python справляется с проблемами, связанными с множественным наследованием.