使用父实现从子类覆盖__mul__:导致问题

时间:2010-11-20 16:03:48

标签: python inheritance

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

所以在C __ mul __中我希望在参数为float时为float实现简单乘法。当它不是我想要使用P的__ mul __ ..但是这会导致问题,就像P的__ mul __那样是“返回P(某事)”..

所以基本上他们最初是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

2 个答案:

答案 0 :(得分:5)

首先,__mul__ MyFloatExt中的类型检查应该是

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

甚至更好

isinstance(other,Number) #from numbers import Number

此外,您还希望将__mul__MyFloat的定义更改为:

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

答案 1 :(得分:1)

这里有两个问题

  1. 在您__mul__的{​​{1}}实施中,您永远不会检查MyFloatExtother的实例

  2. MyFloatExt将永远为真,因为isinstance(e, MyFloat)继承自MyFloatExt

  3. 修复它:

    MyFloat