2017-06-04 114 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數組 - 如果使用得當,它們會使得很多數學操作更快更簡單。

相關問題