python内置列表的__init__方法下面的初始化过程是什么

时间:2017-06-07 16:40:08

标签: python list initialization subclass

我的问题是列表类的 init 方法是否会调用其他方法,例如append或insert来实现其功能。

像:

class test(list):

def __init__(self,values):
    super().__init__()

def append(self, value):
    self.append(value + 1)

我想:

x = test([1,2,3])
x
[2,3,4]

但我得到了:

[1,2,3]

我知道我可以通过重载 init 本身来实现它。

def __init__(self,values):
    super().__init__([x+1 for x in values])

我可以重载一些基本值插入方法,如 setitem ,所以所有插入操作如append,insert都会调用它,因此具有这种附加效果。

感谢任何建议。

2 个答案:

答案 0 :(得分:4)

list.__init__不会调用任何可重写的方法。它为实现extend方法的C函数生成direct, un-overrideable call

if (arg != NULL) {
    PyObject *rv = listextend(self, arg);
    if (rv == NULL)
        return -1;
    Py_DECREF(rv);
}

在C中实现的大多数Python类型的大多数方法都是这种情况。

答案 1 :(得分:0)

我已经看到了另一个覆盖表单collections.MutableSequence的示例,它可以让您获得此功能。我不确定这是否比您最初的想法更方便,但它会在__init__appendinsertextend期间增加任何数字

class IncList(collections.MutableSequence):
    def __init__(self, int_list):
        self._list = []
        for el in int_list:
            self.append(el)

    def __len__(self): return len(self._list)
    def __getitem__(self, item): return self._list[item]
    def __delitem__(self, item): del self._list[item]

    def __setitem__(self, index, value):
        self._list[index] = value + 1

    def insert(self, index, value):
        self._list.insert(index, value + 1)

    def __str__(self):
        return str(self._list)

    def __repr__(self):
        return "%s(%r)" % (self.__class__, self._list)


> l = IncList([1, 2, 3])
> print(l)
[2, 3, 4]
> l.append(4)
> print(l)
[2, 3, 4, 5]
> l[0] = 0
> print(l)
[1, 3, 4, 5]
> l.extend([5, 6])
> print(l)
[1, 3, 4, 5, 6, 7]
> l.insert(1, 1)
> print(l)
[1, 2, 3, 4, 5, 6, 7]

有关详细信息,请参阅this answer