我正在尝试实现 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
