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