Skip to main content
 首页 » 编程设计

python之使用父实现 : leads to problems 从子类覆盖 __mul__

2025年05月04日1798°冷暖

我正在尝试实现 C 类的 __mul__ 方法,该方法扩展了 P 类。类 P 具有 __mul__ 的实现,但这仅适用于该类型的元素 (P() * P())。

所以在 C.__mul__ 中,当参数为 float 时,我想为 float 实现简单的乘法。如果不是,我想使用 P.__mul__ ... 但这会导致问题,如 P.__mul__ 那是 return P(something)...

所以基本上它们最初是 C 类型的事实在一些操作之后就丢失了。

下面的代码更能说明问题。

有什么办法解决这个问题吗?

class MyFloat(object): 
  def __init__(self, a): 
    self.a = a 
 
  def __mul__(self, other): 
    return MyFloat(self.a * other.a) 
 
  def __repr__(self): 
    return str(self.a) 
 
 
class MyFloatExt(MyFloat): 
  def __init__(self, a): 
    MyFloat.__init__(self, a) 
 
  def __add__(self, other): 
    return MyFloatExt(self.a + other.a) 
 
  def __mul__(self, other): 
    if type(other) == (int, long, float): 
      return MyFloatExt(self.a * other) 
    else: 
      return MyFloat.__mul__(self, other) 
 
a = MyFloatExt(0.5) 
b = MyFloatExt(1.5) 
 
c = a + b 
print c 
 
d = a * b 
print d 
 
e = d * c 
print e 
 
print isinstance(e, MyFloat) 
f = e * 0.5 
print f 

请您参考如下方法:

首先,您在 __mul__ 中为 MyFloatExt 进行的类型检查应该看起来像

isinstance(other,(int,long,float)) 

甚至更好

isinstance(other,Number) #from numbers import Number 

您还想将 MyFloat 中 __mul__ 的定义更改为:

class MyFloat(object): 
#... 
  def __mul__(self, other): 
    return type(self)(self.a * other.a) 
#... 

因此它可以创建您实际类型的实例

而且你可以更喜欢调用 super 而不是调用 MyFloat.__mul__ 因为你的类型层次结构的进化原因。

完整来源:

from numbers import Number 
class MyFloat(object): 
  def __init__(self, a): 
    self.a = a 
 
  def __mul__(self, other): 
    return type(self)(self.a * other.a) 
 
  def __repr__(self): 
    return str(self.a) 
 
 
class MyFloatExt(MyFloat): 
  def __init__(self, a): 
    super(MyFloatExt,self).__init__(a) 
 
  def __add__(self, other): 
    return type(self)(self.a + other.a) 
 
  def __mul__(self, other): 
    if isinstance(other,Number): 
      return type(self)(self.a * other) 
    else: 
      return super(MyFloatExt,self).__mul__(other) 
 
 
a = MyFloatExt(0.5) 
b = MyFloatExt(1.5) 
 
c = a + b 
print c 
 
d = a * b 
print d 
 
 
e = d * c 
print e 
 
print isinstance(e, MyFloat) 
 
f = e * 0.5 
print f 
 
print map(type,[a,b,c,d,e,f]) == [MyFloatExt]*6