Completely wrap an object in Python

后端 未结 6 1041
太阳男子
太阳男子 2020-12-23 09:33

I am wanting to completely wrap an object so that all attribute and method requests get forwarded to the object it\'s wrapping, but also overriding any methods or variables

6条回答
  •  抹茶落季
    2020-12-23 10:31

    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.

提交回复
热议问题