将list.insert()方法模拟为Python列表的子类

时间:2011-04-07 19:31:51

标签: python subclass subclassing

我正在尝试构建一个从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)

4 个答案:

答案 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()的方法。这样你就不需要用其他方法来克服它了。