Python 整数 * 浮点数 = NotImplemented

1 投票
1 回答
667 浏览
提问于 2025-04-16 21:40

我在写一个向量类的时候,发现了一个有趣的事实。

>>> 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)

你应该对这个类中的每个其他函数都这样做。

撰写回答