【发布时间】:2017-12-14 02:17:44
【问题描述】:
我有一个代数对象的类层次结构,它们实现了特殊方法,例如__mul__ 和__add__,并使用多重继承。我以某种方式假设 Python (>= 3.5) 会按照方法解析顺序 (mro) 找到第一个不返回 NotImplemented 的方法。唉,情况似乎并非如此。考虑以下最小示例:
class A():
def __mul__(self, other):
return "A * %s" % other
class B():
def __mul__(self, other):
if isinstance(other, int):
return "B * %s" % other
else:
return NotImplemented
class C(B, A):
pass
class D(B, A):
def __mul__(self, other):
res = B.__mul__(self, other)
if res is NotImplemented:
res = A.__mul__(self, other)
return res
在这段代码中,我实现了 D 并具有所需的行为:
>>> d = D()
>>> d * 1
'B * 1'
>>> d * "x"
'A * x'
但是,我实际上预计 C 的行为与 D 相同,但事实并非如此:
>>> c = C()
>>> c * 1
'B * 1'
>>> c * "x"
Traceback (most recent call last):
File "<ipython-input-23-549ffa5b5ffb>", line 1, in <module>
c * "x"
TypeError: can't multiply sequence by non-int of type 'C'
我当然明白发生了什么:我只是返回 mro 中第一个匹配方法的结果(我只是希望 NotImplemented 将作为特殊值处理)
我的问题是,是否有办法绕过编写像 D.__mul__ 这样的样板代码(对于所有数字特殊方法,对于所有类,这基本上是相同的)。我想我可以编写一个类装饰器或元类来自动生成所有这些方法,但我希望有一些更简单的(标准库)方式,或者有人已经做过这样的事情。
【问题讨论】:
标签: python oop multiple-inheritance method-resolution-order