小编典典

自引用列表

python

说您执行以下操作:

a = [1]
a[0] = a

您最终a等于[[...]]。这里发生了什么?这如何隐式地定义的无穷链aa的最终为[[...]]


阅读 220

收藏
2020-12-20

共1个答案

小编典典

您什么都没看到:

>>> a = []
>>> a[:] = [a] * 4
>>> a
[[...], [...], [...], [...]]

如果您对CPython在CPython中的工作方式感兴趣,请参阅list_reprinlistobject.c和类似的函数。基本上,任何可能打印自引用对象的函数都会Py_ReprEnter在对象打印之前和Py_ReprLeave完成时调用该对象。(请参阅参考资料object.c,以获得这些函数的定义。)前者检查是否在当前正在打印的线程局部对象堆栈中找到了该对象(如果没有,则进行推送);后者从堆栈中弹出对象。因此,如果Python正在打印一个列表并发现该列表在堆栈中,则必须表示这是一个自引用列表,并且该列表应缩写,以避免无限循环:

 i = Py_ReprEnter((PyObject*)v);
 if (i != 0) {
     return i > 0 ? PyString_FromString("[...]") : NULL;
 }

 // ...

 Py_ReprLeave((PyObject *)v);
 return result;
2020-12-20