根据文档,super(cls, obj)
returns
将方法调用委托给父级或同级的代理对象
cls 类型的类
我明白为什么super()
提供此功能,但我需要稍微不同的东西:我需要创建一个代理对象,将方法调用(和属性查找)委托给类cls
本身;和如super
, if cls
没有实现方法/属性,我的代理应该继续在 MRO 订单中查找(new不是original班级)。我可以编写任何函数来实现这一目标吗?
Example:
class X:
def act():
#...
class Y:
def act():
#...
class A(X, Y):
def act():
#...
class B(X, Y):
def act():
#...
class C(A, B):
def act():
#...
c = C()
b = some_magic_function(B, c)
# `b` needs to delegate calls to `act` to B, and look up attribute `s` in B
# I will pass `b` somewhere else, and have no control over it
当然,我可以做b = super(A, c)
,但这依赖于了解确切的类层次结构and事实是B
如下A
在 MRO 中。如果这两个假设中的任何一个在未来发生变化,它都会悄然破裂。 (注意super
不做任何这样的假设!)
如果我只需要打电话b.act()
,我可以用B.act(c)
。但我正在路过b
给别人,并且不知道他们会用它做什么。我需要确保它不会背叛我并开始表现得像一个实例class C
在某一点。
一个单独的问题,文档super()
(在 Python 3.2 中)仅讨论其方法委托,并没有阐明代理的属性查找也以相同的方式执行。难道是偶然的遗漏?
EDIT
更新后的委托方法也适用于以下示例:
class A:
def f(self):
print('A.f')
def h(self):
print('A.h')
self.f()
class B(A):
def g(self):
self.f()
print('B.g')
def f(self):
print('B.f')
def t(self):
super().h()
a_true = A()
# instance of A ends up executing A.f
a_true.h()
b = B()
a_proxy = Delegate(A, b)
# *unlike* super(), the updated `Delegate` implementation would call A.f, not B.f
a_proxy.h()
请注意,更新后的class Delegate
比我想要的更接近super()
有两个原因:
super()
它只代理第一次调用;后续调用将照常发生,因为那时将使用该对象,而不是其代理。
super()
不允许属性访问。
因此,我所提出的问题在 Python 中有一个(几乎)完美的答案。
事实证明,在更高的层面上,我试图做一些我不应该做的事情(在这里查看我的评论).