Python 为什么uuu mul_uuuu()需要整数参数?

Python 为什么uuu mul_uuuu()需要整数参数?,python,python-3.x,Python,Python 3.x,我得到TypeError:“float”对象不能解释为整数。似乎\uuuu mul\uuu()需要一个仅限整数的参数。我没有正确地定义它吗 # Running Python 3.6.0 from math import sqrt class Vector(object): def __init__(self, coordinates): try: self.dimension = len(coordinates) if

我得到
TypeError:“float”对象不能解释为整数。似乎
\uuuu mul\uuu()
需要一个仅限整数的参数。我没有正确地定义它吗

# Running Python 3.6.0
from math import sqrt


class Vector(object):
    def __init__(self, coordinates):
        try:
            self.dimension = len(coordinates)
            if self.dimension < 2 or self.dimension > 3:
                raise ValueError
            self.coordinates = tuple(coordinates)

        except ValueError:
            raise ValueError('Must have at least 2 coordinates and no more than 3. Length = {}'.format(self.dimension))

        except TypeError:
            raise TypeError('The coordinates must be an iterable')

        self.magnitude = sqrt(sum([n ** 2 for n in self.coordinates]))

    # This fails with a type error
    def normalized(self):
        try:
            normalized = self.coordinates.__mul__(1.0 / self.magnitude)
        except ZeroDivisionError:
            raise Exception("Cannot normalize zero vector")
        return normalized

    # This fails with a type error
    # def normalized(self):
    #     try:
    #         normalized = self.coordinates * (1.0 / self.magnitude)
    #     except ZeroDivisionError:
    #         raise Exception("Cannot normalize zero vector")
    #     return normalized

    # This works fine
    # def normalized(self):
    #     try:
    #         normalized = [n / self.magnitude for n in self.coordinates]
    #     except ZeroDivisionError:
    #         raise Exception("Cannot normalize zero vector")
    #     return Vector(normalized)

    def __iter__(self):
        return self.coordinates

    def __mul__(self, scalar):
        # Vector scalar multiplication
        return Vector([e * scalar for e in self.coordinates])

    def __str__(self):
        return 'Vector: {}'.format(self.coordinates)


# Run the test...
if __name__ == "__main__":
    v1 = Vector([1.996, 3.108, -4.554])
    print(v1)
    print(v1.normalized())
就本解释而言,其简化为:

a = b.__mul__(c)

这里,
b
是一个元组,
c
是一个数字,一个实数

用Python

(1, 2) * 3
导致

(1, 2, 1, 2, 1, 2)
换句话说,应用于元组的
*
运算符将导致该元组复制N次

这也意味着我们不能用浮点数乘以元组,这是没有意义的。因此出现了错误:

TypeError: 'float' object cannot be interpreted as an integer
有道理

我的错误在于我将元组乘以
self.magnity
,而不是将
Vector
对象乘以
self.magnity
,如下所示:

normalized = self.__mul__(1.0 / self.magnitude)
根据我对
\uuuu mul\uuuu()
的定义,这很有意义,也很好用。这也行得通:

normalized = self * (1.0 / self.magnitude)
(与坐标一样)复制元组的内容以增加其长度,因此仅对整数有意义

您正在尝试将数组的eavh元素乘以一个数字。如果将
坐标设置为numpy数组,则乘法运算符将正确执行此操作。如果要将
坐标保持为元组,则需要对其进行迭代,将每个元素分别相乘(例如,与为向量类定义的
\uuuuuuuuuuuuu
函数类似)

就我个人而言,我建议尽可能使用numpy数组——如果使用得当,它们将使你正在做的许多数学运算更快、更容易。

(就像你的坐标一样)复制元组的内容以增加其长度,因此只对整数有意义

您正在尝试将数组的eavh元素乘以一个数字。如果将
坐标设置为numpy数组,则乘法运算符将正确执行此操作。如果要将
坐标保持为元组,则需要对其进行迭代,将每个元素分别相乘(例如,与为向量类定义的
\uuuuuuuuuuuuu
函数类似)


就我个人而言,我建议尽可能使用numpy数组——如果使用得当,它们将使你正在做的许多数学运算更快、更容易。

你正在将
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>应用到元组
坐标中。返回n个副本,这显然需要一个整数

既然您已经编写了一个
\uuuuuuuuuuuuuuuuuuuuuu
函数,您可能打算调用它

normalized = self.__mul__(1.0 / self.magnitude)
或者直接

normalized = Vector([e * 1.0 / self.magnitude for e in self.coordinates])

您正在将
\uuuu mul\uuuu
应用于元组
坐标
。返回n个副本,这显然需要一个整数

既然您已经编写了一个
\uuuuuuuuuuuuuuuuuuuuuu
函数,您可能打算调用它

normalized = self.__mul__(1.0 / self.magnitude)
或者直接

normalized = Vector([e * 1.0 / self.magnitude for e in self.coordinates])

我想这可能比我的答案更好地猜测OP想要实现什么。你能解释一下应用于元组的
\uuuuu mul\uuuu()
如何返回元组的多个副本吗?列表理解返回一个带有标量乘法结果的新向量对象。我在文档中看不到清晰的语句,但您可以测试它:
(1,2)*2
=
(1,2,1,2)
-就像
'ab'*2
=
'abab'
啊,好的,这就是您的意思。在这种情况下,我定义了乘法,如果我的向量类型包含
(1,2)
,那么
my_Vector*2)
的结果将是一个坐标为
(2,4)
的新向量。换言之,列表或元组不会重复N次。我接受这个答案,并在我理解了发生了什么之后为我的问题添加一些评论/澄清。我认为这可能比我的答案更好地猜测OP想要实现什么。你能解释一下如何
应用于元组会返回元组的多个副本吗?列表理解返回一个带有标量乘法结果的新向量对象。我在文档中看不到清晰的语句,但您可以测试它:
(1,2)*2
=
(1,2,1,2)
-就像
'ab'*2
=
'abab'
啊,好的,这就是您的意思。在这种情况下,我定义了乘法,如果我的向量类型包含
(1,2)
,那么
my_Vector*2)
的结果将是一个坐标为
(2,4)
的新向量。换言之,列表或元组不会重复N次。我接受这个答案,并在我理解发生了什么之后,对我的问题添加一些评论/澄清。