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

Fab*_*ano 1 python inheritance

我正在尝试实现扩展类P的类C的__ mul __方法.类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

Odo*_*ois 5

首先,你在你的类型检测,__mul__MyFloatExt应该像

isinstance(other,(int,long,float))
Run Code Online (Sandbox Code Playgroud)

甚至更好

isinstance(other,Number) #from numbers import Number
Run Code Online (Sandbox Code Playgroud)

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

class MyFloat(object):
#...
  def __mul__(self, other):
    return type(self)(self.a * other.a)
#...
Run Code Online (Sandbox Code Playgroud)

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

你可以更喜欢打电话,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
Run Code Online (Sandbox Code Playgroud)