Python integer*float = NotImplemented

Cea*_*sta 0 python operator-keyword

所以当我发现这个有趣的事实时,我正在乱写一个矢量类.

>>> e = int(3)
>>> e.__mul__(3.0)
NotImplemented
Run Code Online (Sandbox Code Playgroud)

谁能解释为什么会这样,以及随后如何修复我的矢量类?

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))
Run Code Online (Sandbox Code Playgroud)

编辑:更清楚一点:

>>> a = Vector([10, 20])
>>> a
(10, 20)
>>> b = a / 2.0
>>> b
(5.0, 10.0)
>>> 2 * b
(NotImplemented, NotImplemented)
Run Code Online (Sandbox Code Playgroud)

JBe*_*rdo 11

那是因为当你做到 3 * 3.0解释器(3.0).__rmul__(3)在意识到(3).__mul__(3.0)没有实现后调用

Float __mul____rmul__函数会将整数转换为浮点数,但int类不应该发生这种情况.

否则3 * 3.59代替10.5

第二个问题:

为什么人们坚持map列表推导(和生成器表达式)更好?

试试看:

def __mul__(self, scalar):
    return Vector(scalar * j for j in self)
Run Code Online (Sandbox Code Playgroud)

您应该对该类中的其他所有函数执行此操作.

  • @Ceasar没关系,但请记住,理解更具可读性(99.99%的时间),并且是地图/过滤器的最终替代品.永远不会使用Reduce(在Python中)! (3认同)