Самый простой способ в большинстве случаев:
class ObjectWrapper(BaseClass):
def __init__(self, baseObject):
self.__class__ = type(baseObject.__class__.__name__,
(self.__class__, baseObject.__class__),
{})
self.__dict__ = baseObject.__dict__
def overriddenMethod(self):
...
Работая таким образом, т. Е. Переназначая собственные значения __class__
и __dict__
таким образом, вам нужно только предоставить свои переопределения - обычные механизмы получения и установки атрибутов Python сделают все остальное ... в основном .
Вы будете в беде, только если baseObject.__class__
определяет __slots__
, и в этом случае подход множественного наследования не работает, и вам нужен громоздкий __getattr__
(как говорили другие, по крайней мере, вы этого не делаете нужно беспокоиться о том, что он будет вызываться с атрибутами, которые вы переопределяете, поскольку это не так! -), __setattr__
(больший вызов, так как он вызывается для каждого атрибута) и т. д .; и выполнение isinstance
и специальных методов работы требует кропотливой и громоздкой детальной работы.
По сути, __slots__
означает, что класс является особым, каждый экземпляр - это легкий «объект-значение», который НЕ подлежит дальнейшим сложным манипуляциям, переносу и т. Д., Поскольку необходимо сохранять несколько байтов на экземпляр этого класса. отменяет все обычные проблемы с гибкостью и т. д .; поэтому неудивительно, что работа с такими экстремальными, редкими классами таким же плавным и гибким способом, как вы можете иметь дело с 99% + объектов Python, действительно является болью. Так нужно ли вам иметь дело с __slots__
(для написания, тестирования, отладки и обслуживания сотен строк кода только для этих угловых случаев), или будет достаточно 99% -ного решения в полдюжины строк? -)
Следует также отметить, что это может привести к утечкам памяти, поскольку создание подкласса добавляет подкласс в список подклассов базового класса и не удаляется, когда все экземпляры подкласса являются GC'd.