2014-01-17 89 views
2

我想擴展類「list」的功能,併爲事件添加自定義處理程序:「添加新項目到列表」和「從列表中刪除項目」。對於這個任務我不想使用組合,更好的是繼承。Python:擴展列表的正確方式

什麼,我試圖做的事:

class ExtendedList(list): 

    def append(self, obj): 
     super(ExtendedList, self).append(obj) 
     print('Added new item') 

    def extend(self, collection): 
     if (hasattr(collection, '__iter__') or hasattr(collection, '__getitem__')) and len(collection)>0: 
      for item in collection: 
       self.append(item) 

    def insert(self, index, obj): 
     super(ExtendedList, self).insert(index, obj) 
     print('Added new item') 

    def remove(self, value): 
     super(ExtendedList, self).remove(value) 
     print('Item removed') 

但它不能正常工作。我無法捕捉所有添加和刪除事件。例如:

collection = ExtendedList() 
collection.append('First item') 
# Out: "Added new item\n"; collection now is: ['First item'] 
collection.extend(['Second item', 'Third item']) 
# Out: "Added new item\nAdded new item\n"; collection now is: ['First item', 'Second item', 'Third item'] 
collection += ['Four item'] 
# Don't out anythink; collection now is: ['First item', 'Second item', 'Third item', 'Four item'] 
collection.remove('First item') 
# Out: "Item removed\n"; collection now is: ['Second item', 'Third item', 'Four item'] 
del collection[0:2] 
# Don't out anythink; collection now is: ['Four item'] 
collection *= 3 
# Don't out anythink; collection now is: ['Four item', 'Four item', 'Four item'] 

什麼是正確的方式來擴展我的情況類「列表」?感謝幫助。

+1

在這裏定義列表的子類不是一個好主意。相反,你應該傾向於繼承聚合 – gefei

+0

這些都做不同的事情,所以使用一個更適合你想要完成的事情? – brandonscript

+1

你已經展示了會發生什麼,但是它有什麼問題?你想要發生什麼? – nmichaels

回答

5

而不是繼承自list本身,繼承自其抽象基類,collections.MutableSequence。這爲您完成所有基本工作,讓您專注於您想要更改的內容。在ABCs here上有一個很好的問題。

1

看看這個班級UserList:http://pydoc.org/2.2.3/UserList.html 它顯示你需要改變的所有方法。 問題是type(ExtendedList([]) * 2) == list

+1

這是一個非常過時的答案。 Python 2.2+在擴展'list'方面沒有問題,從2.3開始,「問題」已經有了一個解決方案,2.6+有['MutableSequence'](http://docs.python.org/2/library/collections。html#collections-abstract-base-classes)ABC,刪除任何人再次查看'UserList'的最後一個原因,這就是爲什麼它被完全棄用並從文檔中刪除的原因。 – abarnert

+0

沒錯。現在已經過時了。只是不記得MutableSequence。 – User

+0

對不起,它在3.0中被刪除,而不是2.6。 2.6將它和[其他相關的過時模塊](http://docs.python.org/2.6/library/userdict.html?highlight=userlist#module-UserList)組合成一個單獨的頁面,提醒你每隔幾句話「注意:此模塊僅可用於向後兼容。「不過,這不是一個好建議。尤其是對於一個看起來像是在使用Python 3.x的OP。 – abarnert

3

操作,如*=+=,並del使用的是像__add____delitem____delslice__list類的操作功能實現等方面有很多很多。如果你想攔截所有可能的調用你的「擴展」列表類,你需要覆蓋大部分(如果不是全部)這些運算符。

因爲你沒有在內置類是如何實現的控制,它通常是更容易組成一類新的圍繞一個內建比繼承從內置。

+0

似乎,我錯了,真的更好使用聚合或從MutableSequence繼承... – uzumaxy

2

如果你想覆蓋+這樣的運算符,你需要明確地做。 The documentation將幫助您找出需要更改的內容。