我正在尝试构建一个从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的列表()的建议
生成的代码......发布在这里,以防万一...
from collections 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):
"""Get a list item"""
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)
答案 0 :(得分:7)
如果你可以避免它,不要继承内置类。 (你可以,但这并不意味着你应该没有真正令人信服的理由)
这些类针对速度进行了优化,这使得正确继承它们非常繁琐,因为你最终必须覆盖几乎所有内容。
继承collections.MutableSequence
只允许您实现一些基本方法,并获得序列API的强大的全功能实现,而不会继承list
所带来的所有怪癖和警告。 / p>
答案 1 :(得分:6)
使用isinstance
检查您的对象是否是Host
的实例,并使用super
(例如super(HostList, self).insert(...)
)来使用{{1}的功能而不是自己重新实现它。
你应该得到类似的东西:
list
答案 2 :(得分:3)
除非有令人信服的理由让你的HostList容器完全支持可变容器接口,否则我建议使用has-a模型而不是is-a。您将有额外的负担来确保类型与切片等操作的一致性(返回HostList容器而不是列表)。
答案 3 :(得分:0)
您可以使用list
从您的方法调用super()
的方法。这样你就不需要用其他方法来克服它了。