2017-06-22 46 views
1

我有一個類添加了兩個點(其中一個是類型Point,另一個是元組或列表 - 請參閱代碼)。我的問題是,我的方法將只會工作,如果我輸入一定的順序的數字。我需要創建第二個方法(根據此作業中的規則),它只包含一行,調用add方法,並返回結果,並且可以在文檔的數據模型中找到。Python 3的方法在一個加法操作中翻轉參數

class Point(): 
def __init__(self, x=0, y=0): 
    self.x = x 
    self.y = y 

def __str__(self): 
    return ("X = " + str(self.x) + "\nY = " + str(self.y)) 

def __add__(self, other): 
    if isinstance(other,list) or isinstance(other,tuple): 
     newX = other[0] + self.x 
     newY = other[1] + self.y 
     return(Point(newX,newY)) 
    else: 
     newX = self.x + other 
     newY = self.y + other 
     return(Point(newX,newY)) 

p = Point(5,10) 
print(p + [3.5,6]) 
print([3.5,6] + p) 

我已經沖刷的數據模型,我只能認爲逆轉什麼用GETATTR會的工作,但我不知道如何實現兩種,或者如果我連上正確的軌道上。請幫忙!

回答

0

你應該在你的類中添加__radd__()

def __radd__(self, *args, **kwargs): 
    return self.__add__(*args, **kwargs) 

這實際上做一個__add__()在這種情況下,它確實是一樣的。

,但你可以考慮使類的行爲像一個列表,像這樣:

class Point(): 
    def __init__(self, x=0, y=0): 
     self.x = x 
     self.y = y 
     self._list = [self.x, self.y] 

    def __str__(self): 
     return ("X = " + str(self.x) + "\nY = " + str(self.y)) 

    def __repr__(self): 
     return str(self._list) 

    def __iter__(self): 
     for elem in self._list: 
      yield elem 

    def __getitem__(self, i): 
     return self._list(i) 

    def __len__(self): 
     return len(self._list) 

    def __delitem__(self, i): 
     #not sure if you really want this 
     del self._list[i] 

    def __setitem__(self, i, val): 
     #not sure if you really want this 
     self._list[i] = val  

    def __add__(self, other): 
     #this code could be optimized 
     #using your original code for this example 
     if isinstance(other,list) or isinstance(other,tuple): 
      newX = other[0] + self.x 
      newY = other[1] + self.y 
     else: 
      newX = self.x + other 
      newY = self.y + other 
     #returning a list 
     return [newX, newY] 

    def __radd__(self, *args, **kwargs): 
     return self.__add__(*args, **kwargs) 


p = Point(5,10) 
print(p) 
print(p + [3.5,6]) 
print([3.5,6] + p) 

輸出:

[5, 10] 
[8.5, 16] 
[8.5, 16] 

[編輯]如果你決定要讓它像一個list ,你不妨繼承list,例如:

class Point(list): 

    def __init__(self, x=0, y=0): 
     super(Point, self).__init__([x, y]) 

    def __add__(self, other): 
     if isinstance(other, (list, tuple)): 
      return [sum(i) for i in zip(self, other)] 
     elif isinstance(other, (int, float)): 
      return [i + other for i in self] 
     else: 
      return self 

    def __radd__(self, *args, **kwargs): 
     return self.__add__(*args, **kwargs) 

    #you probably want a __sub__ 
    def __sub__(self, other): 
     if isinstance(other, (list, tuple)): 
      return [i - j for i, j in zip(self, other)] 
     elif isinstance(other, (int, float)): 
      return [i - other for i in self] 
     else: 
      return self 

    #and an __rsub__ 
    def __rsub__(self, other): 
     if isinstance(other, (list, tuple)): 
      return [i - j for i, j in zip(other, self)] 
     elif isinstance(other, (int, float)): 
      return [other - i for i in self] 
     else: 
      return self 

    #take away functions you do not want 
    def pop(*args, **kwargs): pass 
    def sort(*args, **kwargs): pass 
    def append(*args, **kwargs): pass 
    def extend(*args, **kwargs): pass 
    def insert(*args, **kwargs): pass 
    def remove(*args, **kwargs): pass 
    def reverse(*args, **kwargs): pass 

p = Point(5,10) 
tests = [[3.5, 6], (5,4), 1.1, 'wrong string', [1, 2, 3]] 
for test in tests: 
    print(p + test) 
    print(test + p) 
for test in tests: 
    print(p - test) 
    print(test - p) 
p.append(4) 
print(p) 

輸出:

[8.5, 16] 
[8.5, 16] 
[10, 14] 
[10, 14] 
[6.1, 11.1] 
[6.1, 11.1] 
[5, 10] 
[5, 10] 
[6, 12] 
[6, 12] 
[1.5, 4] 
[-1.5, -4] 
[0, 6] 
[0, -6] 
[3.9, 8.9] 
[-3.9, -8.9] 
[5, 10] 
[5, 10] 
[4, 8] 
[-4, -8] 
[5, 10] 
+0

我明顯沒有讀得很好。感謝您的幫助! – vandy

+0

@vandy,我用一個子類列表的例子更新了答案,這使得代碼更易於管理 –

相關問題