The simplest way in most cases is probably:
class ObjectWrapper(BaseClass):
def __init__(self, baseObject):
self.__class__ = type(baseObject.__class__.__name__,
(self.__class__, baseObject.__class__),
{})
self.__dict__ = baseObject.__dict__
def overriddenMethod(self):
...
Working in this way, i.e. by reassigning self's __class__
and __dict__
in this fashion, you need only provide your overrides -- Python's normal attribute getting and setting mechanisms will do the rest... mostly.
You'll be in trouble only if baseObject.__class__
defines __slots__
, in which case the multiple inheritance approach doesn't work and you do need the cumbersome __getattr__
(as others said, at least you don't need to worry that it will be called with attributes you're overriding, as it won't!-), __setattr__
(a greater pain, as it DOES get called for every attribute), etc; and making isinstance
and special methods work takes painstaking and cumbersome detailed work.
Essentially, __slots__
means that a class is a special, each instance a lightweight "value object" NOT to be subject to further sophisticated manipulation, wrapping, etc, because the need to save a few bytes per instance of that class overrides all the normal concerns about flexibility and so on; it's therefore not surprising that dealing with such extreme, rare classes in the same smooth and flexible way as you can deal with 99%+ of Python objects is truly a pain. So DO you need to deal with __slots__
(to the point of writing, testing, debugging and maintaining hundreds of lines of code just for those corner cases), or will the 99% solution in half a dozen lines suffice?-)
It should also be noted that this may lead to memory leaks, as creating a subclass adds the subclass to the base class' list of subclasses, and isn't removed when all instances of the subclass are GC'd.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…