如果您尝试将大量属性从任何 A 对象委托给其b
成员,那么在 、 和 中执行此操作可能更容易__getattr__
,__setattr__
例如__delattr__
:
class A(object):
delegated = ['c', 'd', 'e', 'f']
def __getattr__(self, attr):
if attr in A.delegated:
return getattr(self.b, attr)
raise AttributeError()
为了简洁起见,为了避免解释和之间的区别,我没有在这里展示and 的__setattr__
定义。如果您需要更多信息,请参阅文档。__delattr__
__getattr__
__getattribute__
这很容易扩展到想要将不同属性代理给不同成员的类:
class A(object):
b_delegated = ['c', 'd', 'e', 'f']
x_delegated = ['y', 'z']
def __getattr__(self, attr):
if attr in A.b_delegated:
return getattr(self.b, attr)
elif attr in A.x_delegated:
return getattr(self.x, attr)
else:
raise AttributeError()
如果您需要动态地委托所有属性,那几乎同样简单。您只需在初始化时或调用时(四种可能性中的哪一种取决于您想要做什么)获得一个self.b
's 属性(或's)列表,并使用它来代替静态列表。self.b.__class__
b_delegated
您当然可以按名称(例如,删除_private
方法)、类型或任意谓词(例如,删除任何callable
属性)过滤它。
或者结合以上任何一种。
无论如何,这是在 Python 中进行(尤其是动态)代理的惯用方式。它并不完美,但尝试发明一种不同的机制可能不是一个好主意。
事实上,它并不意味着完美。这是你不应该经常做的事情,也不应该在你做的时候试图掩饰。很明显,一个ctypes.cdll
或一个pyobjc
模块实际上是委托给别的东西,因为它实际上对用户知道这一点很有用。如果您确实需要将一个类的大部分公共接口委托给另一个类,并且不希望用户知道委托……也许您不需要它。也许最好直接公开私有对象,或者重新组织您的对象模型,以便用户首先与正确的事物进行交互。