Оказывается, что можно динамически изменять Base.__bases__
если Base.__base__
не object
. (Динамически меняя, я имею в виду таким образом, что все ранее существовавшие экземпляры, которые наследуют от Base
, также динамически меняются. В противном случае см. Mykola Kharechko's solution).
Base.__base__
Если некоторый фиктивный класс TopBase
, то назначение Base.__bases__
, кажется, работает:
class Extender(object):
def extension(self):
print("Some work...")
class TopBase(object):
pass
class Base(TopBase):
pass
b=Base()
print(Base.__bases__)
# (<class '__main__.TopBase'>,)
Base.__bases__ += (Extender,)
print(Base.__bases__)
# (<class '__main__.TopBase'>, <class '__main__.Extender'>)
Base().extension()
# Some work...
b.extension()
# Some work...
Base.__bases__ = (Extender, TopBase)
print(Base.__bases__)
# (<class '__main__.Extender'>, <class '__main__.TopBase'>)
Base().extension()
# Some work...
b.extension()
# Some work...
Это был протестирован для работы в Python 2 (для классов новый- и старого стиля) и Python 3. Я не знаю, почему это работает, пока это не так:
class Extender(object):
def extension(self):
print("Some work...")
class Base(object):
pass
Base.__bases__ = (Extender, object)
# TypeError: __bases__ assignment: 'Extender' deallocator differs from 'object'
Ваши базы больше не принадлежат вам? И ответ будет тяжелым? – Borealid
Я думаю, что это уже невозможно, так как все классы являются классами нового стиля в Python 3, а MRO будет неоднозначным, если в «Base» были как «object», так и «Extender» в качестве базовых классов. Создайте новый класс, который наследуется от 'Base' и' Extender' вместо этого. «Расширитель» также может быть ABC. – Philipp