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

6 投票
5 回答
2052 浏览
提问于 2025-04-16 15:18

我正在尝试创建一个类,这个类可以继承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())。如果我尝试支持所有这些方法,就会出现递归循环的问题。解决这个问题的最佳方法是什么呢?

补充一下……请查看我的最终答案,这是基于下面Nick的建议……

5 个回答

2

除非你有很强的理由让你的 HostList 容器完全支持可变容器的接口,否则我建议使用“包含”模型,而不是“是”模型。这样做会让你在操作时,比如切片(返回一个 HostList 容器而不是一个列表),需要额外注意类型的一致性。

5

使用 isinstance 来检查你的对象,看看它们是否是 Host 的实例。同时,使用 super(比如 super(HostList, self).insert(...))来调用 list 的功能,而不是自己重新实现一遍。

最后你应该得到类似这样的代码:

def append(self, obj): 
    """append to the list..."""
    if not isinstance(obj, Host):
        raise RuntimeError, "Cannot append a '%s' object to a HostList" % obj.__class__.__name__
    super(HostList, self).append(obj)
7

如果可以的话,尽量不要从内置类继承。你可以这样做,但这并不意味着你应该这样做,除非有非常充分的理由。

这些内置类是为了速度优化的,所以从它们继承会变得相当麻烦,因为你几乎需要重写所有东西。

而如果你从 collections.MutableSequence 继承,就只需要实现几个基本的方法,就能得到一个功能齐全的序列接口,而不需要处理从 list 继承时遇到的各种问题和注意事项。

撰写回答