You ain't seen nothing:
>>> a = []
>>> a[:] = [a] * 4
>>> a
[[...], [...], [...], [...]]
If you're interested in how this works in CPython, see list_repr
in listobject.c
and similar functions. Basically, any function that potentially prints a self-referential object calls Py_ReprEnter
on the object before printing it and Py_ReprLeave
when it is done. (See object.c
for the definitions of these functions.) The former checks to see if the object is found in a thread-local stack of objects that are currently being printed (and if not, pushes it); the latter pops the object from the stack. So if Python is printing a list and discovers that the list is on the stack, that must mean that this is a self-referential list, and the list should be abbreviated, to avoid an infinite loop:
i = Py_ReprEnter((PyObject*)v);
if (i != 0) {
return i > 0 ? PyString_FromString("[...]") : NULL;
}
// ...
Py_ReprLeave((PyObject *)v);
return result;
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…