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()
没有骰子。那么到底print
在幕后到底在做什么呢?
(有趣的是,这种行为在 Python 3 中是“固定的”:打印自引用元组会给出省略号截断的形式。)