Override __mul__ from a child class using parent implementation: leads to problems
我正在尝试实现类C的_uuumul_uuuu方法,它扩展了类P。类P有一个_uuuumul_uuu的实现,但这只适用于该类型的元素(p()*p())。
所以在c_uuumul中,当参数为float时,我想为float实现简单的乘法。如果不是的话,我想用P's_uuuuuuuuuuu。但这会导致一些问题,如P's_uuuuumul_uuuuuuuu,这是一个"返回P(某物)"。
所以基本上,它们最初是C型的,在一些操作之后会丢失。
下面的代码可以更好地解释这个问题。
有办法解决这个吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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 |
首先,您在
1 | isinstance(other,(int,long,float)) |
甚至更好
1 | isinstance(other,Number) #from numbers import Number |
另外,您想将
1 2 3 4 5 | class MyFloat(object): #... def __mul__(self, other): return type(self)(self.a * other.a) #... |
因此它可以创建实际类型的实例
您可以选择调用
完整来源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 | def __mul__(self, other): # check if we deal with a MyFloatExt instance if isinstance(other, MyFloatExt): return MyFloatExt(self.a * other.a) if type(other) == (int, long, float): return MyFloatExt(self.a * other) else: return MyFloat.__mul__(self, other) # do the correct check print isinstance(e, MyFloatExt) |