Python的print
语句通常打印其输入的repr()
。元组似乎不是一个例外:
>>> print (1, 2, 3)
(1, 2, 3)
>>> print repr((1, 2, 3))
(1, 2, 3)
但后来我在研究CPython内部时发现了一些奇怪的行为。简而言之:如果你让Python 2创建一个自引用元组,直接打印它的表现与打印它的repr()
/str()
/unicode()
表示形式完全不同。
>>> print outer # refer to the link above
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
... many lines later ...
((((((((((Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError: stack overflow
>>> print repr(outer)
((...),)
>>> print str(outer)
((...),)
>>> print unicode(outer)
((...),)
那么print
到底在做什么?为了回答这个问题,我参考了语言参考:
6.6.
字符串转换规则如下:
5.2.9. 字符串转换
字符串转换是一个用反引号(也叫反撇号)括起来的表达式列表:
string_conversion ::= "`" expression_list "`"
但是用反引号括起来的
outer
与调用repr()
和相关函数得到的结果相同。没有效果。那么(有趣的是,这种行为在Python 3中被“修复”:打印自己引用的元组会给出省略号截断的形式。)
struct.error: 'I' format requires 0 <= number <= 4294967295
的错误。 - thefourtheyec_outer[inner_index:inner_index+4] = struct.pack('Q', id(outer))
处失败,显示ValueError: Can only assign sequence of same size
。 - thefourtheye+4
替换为+8
。 编辑:我已更新链接的Gist,现在应该可以在32位和64位平台上运行。 - ashastralhttp://bugs.python.org/issue1069092
- Ned Deilyinternal_print
(大约在object.c: 315
附近)和tupleprint
(大约在tupleobject.c: 253
附近)之间的递归调用循环引起的。Python 3.2中解决了递归容器reprs问题:http://bugs.python.org/issue9840。 - Ned Deily