2017-03-06 64 views
1

我想重載UserList方法(添加,附加,擴展)來獲取沒有重複。由於某種原因,我仍然得到兩次alpha。我甚至得到一個空列表,如果我只是嘗試打印original_list這是我寫的代碼:UserList重載python 3.x

#!/usr/bin/env python 
#coding: utf-8 

from collections import UserList 

class Ulist(UserList): 
    def __init__(self, info = []): 
     UserList.__init__(self) 
     self.info = info 

    def __add__(self, something_new): 
     for i in something_new: 
      if i in self: 
       print('%r This is already in the list.' % (i)) 
      else: 
       return UserList.__add__(self, something_new) 

    def append(self, something_new): 
     if something_new in self: 
      print('%r This is already in the list.' % (i)) 
     else: 
      return UserList.append(self, something_new) 

    def extend(self, something_new): 
     for i in something_new: 
      if i in self: 
       print('%r This is already in the list.' % (i)) 
      else: 
       return UserList.extend(self, something_new) 


# let's test how it works 

original_list = Ulist(['alpha']) 

original_list.__add__([444]) 
original_list.append('alpha') 
original_list.append('I_dont_exist_yet') 
original_list.append(0) 
original_list.extend([98, 98, 234,'alpha','beta','I_am_totally_new',33]) 


print(original_list) 

免責聲明:我知道人們已經要求有關的UserList和方法重載類似的問題。我分析了這些問題,但仍然無法弄清楚爲什麼我的代碼不起作用。另外,我是Python的新手。

+0

在'extend'函數中,您想要逐個添加每個新元素。不要調用'UserList.extend(something_new)',調用'UserList.append(i)'。 –

+0

a)爲什麼不直接繼承''list''本身?不再需要UserList。 b)如果你不想重複,使用''set''類型。 –

+0

謝謝。所有的建議都很有幫助,但我試圖重載這些特定的方法,而不想使用其他任何方法。 –

回答

0

你想要做這樣的事嗎?

from collections import UserList 

class Ulist(UserList): 
    def __init__(self, info = []): 
     UserList.__init__(self) 
     self.info = info 

    def add_iterable(self, iterable): 
     for i in iterable: 
      if i in self: 
       print('%r This is already in the list.' % (i)) 
      else: 
       UserList.append(self, i) 
     return self 

    def __add__(self, something_new): 
     if hasattr(something_new, '__iter__'): 
      return self.add_iterable(something_new) 
     else: 
      return UserList.append(self, something_new) 

    def append(self, something_new): 
     if something_new in self: 
      print('%r This is already in the list.' % (i)) 
     else: 
      return UserList.append(self, something_new) 

    def extend(self, something_new):   
     return self.add_iterable(something_new) 

測試輸出:

98這已經是在列表中。

'alpha'這已經在列表中。

[444, '阿爾法', 'I_dont_exist_yet',0,98,234, '測試', 'I_am_totally_new',33]

+0

非常感謝!這絕對是完美的。正是我的意思。 (由於我的代表<15,我不能正式表示讚賞你。) –

+0

太好了。別擔心。我相信你至少可以接受一個答案,不管你的代表 –

1

這僅是切向一個答案,但我強烈推薦試圖以彼此的方式實施類似的行動。例如,__add__實際上只是構造,然後是extend操作。而extend實際上只是重複append s。如果性能不是絕對關鍵的(當你實施自己的UserList時,你已經放棄了性能,總的來說),讓一個已知的良好實現和實現其他已知好處的操作變得更容易操作。

因此,例如,__add__可以實現爲:

def __add__(self, other): 
    ret = self.__class__(self) # Alt: self.copy() 
    ret.extend(other) 
    return ret 

所以現在只要你的構造和extend方法是正確的,__add__是自動更正。

然後你在append方面實現extend

def extend(self, other): 
    for x in other: 
     self.append(x) 

現在,如果append是正確的,那麼是extend__add__。現在,你需要做的就是得到append(你可以單獨測試它,直到你確定它是正確的)。

碰巧,您的append已經是正確的(假設print是報告錯誤的合理方式,通常不會)。所以這個__add__extend,和一個工作初始化方法,你會有工作代碼。

無論如何,您的現有代碼實際上並不會正確運行。你的初始化是錯誤的;您將self.info設置爲可迭代的輸入,但self.info從不使用collections.UserList(它使用data屬性)。如果你想製作一個安全的初始化工具,請執行如下操作:

def __init__(self, info=()): # Never use mutable default arguments 
    UserList.__init__(self) 
    self.extend(info) # Reuse known good code 

此外,此操作重用已知良好的代碼;如果extend有效(依次取決於append),那麼這個初始化器是好的。如果您想爲複製方案進行了優化,可以使用類的內部保存重複檢查工作:

def __init__(self, info=()): 
    UserList.__init__(self) 
    if isinstance(info, Ulist): 
     # Already deduped, copy without duplicate checking 
     self.data[:] = info.data 
    else: 
     self.extend(info) 

這個答案的要點是:從片,don't repeat yourself (mnemonic: DRY)積聚。當他們彼此變化時,不要嘗試從頭開始實施每種方法。確定一個單一的「公分母」功能,並在此基礎上進行構建,因此任何給定的方法都可以做一件簡單的事情,或者以最小化自定義代碼的方式用另一種方法實現。

+0

感謝您的全面解釋。一定會牢記這一點! –