2017-06-04 72 views
0

我收到了TypeError: 'float' object cannot be interpreted as an integer。看起来__mul__()正在等待一个仅有整数的参数。我没有正确定义它吗?为什么__mul __()期望整型参数?

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

编辑:

现在我明白了想发生了什么事我澄清答案谁在将来可能会碰上这种人。

的问题在这里:

normalized = self.coordinates.__mul__(1.0/self.magnitude) 

其中,对于这种解释的目的简化为:

a = b.__mul__(c) 

a = b * c 

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

在Python

(1, 2) * 3 

导致

(1, 2, 1, 2, 1, 2) 

*操作者施加在元组的结果的该元组N次复制换句话说。

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

TypeError: 'float' object cannot be interpreted as an integer 

有道理。

我的错误是在我被self.magnitude乘以元组,而不是由self.magnitude乘我Vector对象,像这样:

normalized = self.__mul__(1.0/self.magnitude) 

鉴于我的__mul__()定义这是有道理的,并能正常工作。而这个工程太:

normalized = self * (1.0/self.magnitude) 

回答

2

您正在将__mul__应用于元组coordinates。这返回n个副本,这显然需要一个整数。

既然你已经写了一个__mul__功能,你可能意味着调用

normalized = self.__mul__(1.0/self.magnitude) 

或直接

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

我想,这大概是什么OP正在努力实现比一个更好的猜测我的答案。 – DavidW

+0

你能解释一下如何将'__mul __()'应用于元组返回多个元组的副本吗?列表理解返回一个新的Vector对象,其中包含标量乘法的结果。 –

+0

我在文档中看不到明确的声明,但您可以测试它:'(1,2)* 2' ='(1,2,1,2)' - 就像'ab'* 2' =''abab'' –

2

__mul__ applied to a tuple(如您的坐标)复制数组的内容,以增加它的长度,因此才有意义与整数。

您试图将一个数组的eavh元素乘以一个数字。如果你使coordinates是一个numpy数组,那么乘法运算符会正确地做到这一点。如果你想保留coordinates作为一个元组,那么你将需要遍历它,每个元素分别乘以每个元素(例如,在为矢量类定义的__mul__函数中)。

就我个人而言,如果可能的话,我推荐使用numpy数组 - 如果使用得当,它们会使得很多数学操作更快更简单。

相关问题