2014-01-17 56 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将帮助您找出需要更改的内容。