【发布时间】:2011-04-07 19:31:51
【问题描述】:
我正在尝试构建一个继承 Python 列表中的方法的类,但还做了一些额外的事情......此时仅显示代码可能更容易......
class Host(object):
"""Emulate a virtual host attached to a physical interface"""
def __init__(self):
# Insert class properties here...
pass
class HostList(list):
"""A container for managing lists of hosts"""
def __init__(self):
self = []
def append(self, hostobj):
"""append to the list..."""
if hostobj.__class__.__name__ == 'Host':
self.insert(len(self), hostobj)
else:
_classname = hostobj.__class__.__name__
raise RuntimeError, "Cannot append a '%s' object to a HostList" % _classname
我的问题是...如果我想在 insert() 上执行与在 append() 上相同的对象接纳测试,我找不到在不牺牲支持的情况下编写新方法的方法对于一种列表扩展方法(即list.append()、list.insert() 或list.extend())。如果我尝试支持所有这些,我会以递归循环结束。解决此问题的最佳方法是什么?
编辑:我接受了关于子类化 collections.MutableSequence 而不是 Python 的 list() 的建议
生成的代码...张贴在这里以防万一,它可以帮助某人...
from collections.abc import MutableSequence
class HostList(MutableSequence):
"""A container for manipulating lists of hosts"""
def __init__(self, data):
super(HostList, self).__init__()
if (data is not None):
self._list = list(data)
else:
self._list = list()
def __repr__(self):
return "<{0} {1}>".format(self.__class__.__name__, self._list)
def __len__(self):
"""List length"""
return len(self._list)
def __getitem__(self, ii):
# Good MutableSequence() implementation example in the cpython git repo:
# https://github.com/python/cpython/blob/208a7e957b812ad3b3733791845447677a704f3e/Lib/collections/__init__.py#L1215
if isinstance(ii, slice):
return self.__class__(self._list[ii])
else:
return self._list[ii]
def __delitem__(self, ii):
"""Delete an item"""
del self._list[ii]
def __setitem__(self, ii, val):
# optional: self._acl_check(val)
return self._list[ii]
def __str__(self):
return str(self._list)
def insert(self, ii, val):
# optional: self._acl_check(val)
self._list.insert(ii, val)
def append(self, val):
self.insert(len(self._list), val)
【问题讨论】:
-
self = []并没有按照你的想法去做。 -
super(HostList, self).__init__(self)可以解决问题。您的代码所做的是将(参数)变量self重新分配给[]。 -
如果指定了切片,
__getitem__将返回一个列表对象。您可以将初始值设定项更改为__init__(self, l = None),如果提供,它将使用列表。然后在__getitem__中,如果ii是切片对象,则返回HostList(self._list[ii]) -
另外,您不必定义
append()方法,因为MutableSequence已经为您完成了,只要您定义了insert()方法(查看 hg.python.org/cpython/file/3.4/Lib/_collections_abc.py#l711 了解更多信息信息)。 -
PyCharm 告诉我您缺少几个抽象方法:
__iter__()和__contains__()。
标签: python list subclassing