我想完全包装一个对象,以便所有属性和方法请求都转发到它所包装的对象,但也覆盖我想要的任何方法或变量,以及提供一些我自己的方法。这个包装类应该 100% 显示为现有类(isinstance
必须像它实际上是类一样),但是子类化本身不会削减它,因为我想包装现有的 < em>对象。 Python中有一些解决方案可以做到这一点吗?我的想法是这样的:
class ObjectWrapper(BaseClass):
def __init__(self, baseObject):
self.baseObject = baseObject
def overriddenMethod(self):
...
def myOwnMethod1(self):
...
...
def __getattr__(self, attr):
if attr in ['overriddenMethod', 'myOwnMethod1', 'myOwnMethod2', ...]
# return the requested method
else:
return getattr(self.baseObject, attr)
但我对重写 __getattr__
、__setattr__
和 __hasattr__
不太熟悉,所以我不确定如何正确处理.
最佳答案
大多数情况下最简单的方法大概是:
class ObjectWrapper(BaseClass):
def __init__(self, baseObject):
self.__class__ = type(baseObject.__class__.__name__,
(self.__class__, baseObject.__class__),
{})
self.__dict__ = baseObject.__dict__
def overriddenMethod(self):
...
以这种方式工作,即通过以这种方式重新分配 self 的 __class__
和 __dict__
,您只需要提供覆盖 - Python 的正常属性获取和设置机制就可以了其余的......大部分。
只有 baseObject.__class__
定义了 __slots__
才会有麻烦,在这种情况下,多重继承方法不起作用,您确实需要繁琐的 __getattr__
(正如其他人所说,至少你不必担心它会被你覆盖的属性调用,因为它不会!-),__setattr__
(更大的痛苦,因为每个属性都会调用它)等;而让isinstance
等特殊方法发挥作用是一项艰巨而繁琐的细致工作。
从本质上讲,__slots__
意味着一个类是特殊的,每个实例都是一个轻量级的“值对象”,不需要进行进一步复杂的操作、包装等,因为需要节省几个字节该类的每个实例都会覆盖所有关于灵 active 等的正常问题;因此,以与处理 99% 以上的 Python 对象相同的流畅和灵活的方式处理如此极端、稀有的类确实是一种痛苦,这并不奇怪。因此,您是否需要处理 __slots__
(为了那些极端情况而编写、测试、调试和维护数百行代码),或者将 99% 的解决方案只用六行够了吗?-)
还应该注意,这可能会导致内存泄漏,因为创建子类会将子类添加到基类的子类列表中,并且不会在子类的所有实例都被 GC 时删除。
关于python - 在 Python 中完全包装一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1443129/