我正在尝试实现类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
答案 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)
这里有两个问题
在您__mul__
的{{1}}实施中,您永远不会检查MyFloatExt
是other
的实例
MyFloatExt
将永远为真,因为isinstance(e, MyFloat)
继承自MyFloatExt
修复它:
MyFloat