Python 整数 * 浮点数 = NotImplemented
我在写一个向量类的时候,发现了一个有趣的事实。
>>> e = int(3)
>>> e.__mul__(3.0)
NotImplemented
有没有人能解释一下这是为什么?还有,怎么修复我的向量类呢?
class Vector(tuple):
'''A vector representation.'''
def __init__(self, iterable):
super(Vector, self).__init__(iterable)
def __add__(self, other):
return Vector(map(operator.add, self, other))
def __sub__(self, other):
return Vector(map(operator.sub, self, other))
def __mul__(self, scalar):
return Vector(map(scalar.__mul__, self))
def __rmul__(self, scalar):
return Vector(map(scalar.__mul__, self))
def __div__(self, scalar):
return Vector(map(scalar.__rdiv__, self))
补充说明:为了更清楚一点:
>>> a = Vector([10, 20])
>>> a
(10, 20)
>>> b = a / 2.0
>>> b
(5.0, 10.0)
>>> 2 * b
(NotImplemented, NotImplemented)
1 个回答
12
这是因为当你执行 3 * 3.0
时,解释器会先尝试用 (3).__mul__(3.0)
来计算,但发现这个方法没有实现,所以它会转而调用 (3.0).__rmul__(3)
。
浮点数的 __mul__
和 __rmul__
函数会把整数转换成浮点数,但对于整数类来说,这种转换是不应该发生的。
否则,像 3 * 3.5
这样的计算结果就会是 9
而不是 10.5
。
第二个问题:
为什么人们还是坚持使用 map
,而列表推导式(和生成器表达式)其实更好呢?
试试这个:
def __mul__(self, scalar):
return Vector(scalar * j for j in self)
你应该对这个类中的每个其他函数都这样做。