python - Python 2 使用什么方法打印元组?

标签 python python-2.7 self-reference cpython python-internals

Python 的print 语句通常似乎打印其输入的repr()。元组似乎也不异常(exception):

>>> print (1, 2, 3)
(1, 2, 3)
>>> print repr((1, 2, 3))
(1, 2, 3)

但后来我在 messing around with CPython's internals 时偶然发现了一些奇怪的行为.简而言之:如果你欺骗 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. The print statement

print evaluates each expression in turn and writes the resulting object to standard output (see below). If an object is not a string, it is first converted to a string using the rules for string conversions.

字符串转换的规则是:

5.2.9. String conversions

A string conversion is an expression list enclosed in reverse (a.k.a. backward) quotes:

string_conversion ::=  "`" expression_list "`"

但是将 outer 括在反引号中与调用 repr() 和 friends 的结果相同。没有骰子。那么 print 究竟在幕后做什么呢?

(有趣的是,该行为在 Python 3 中是“固定的”:打印自引用元组会给出省略号截断形式。)

最佳答案

你可以通过反汇编 python 字节码来了解实际发生了什么。

>>> from dis import dis
>>> dis(compile('print outer', '<string>', 'exec'))
  1           0 LOAD_NAME                0 (outer)
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       
              5 LOAD_CONST               0 (None)
              8 RETURN_VALUE

并阅读底层操作码的源代码。

PRINT_ITEM最终到达这段代码:

else if (Py_TYPE(op)->tp_print == NULL) {
    PyObject *s;
    if (flags & Py_PRINT_RAW)
        s = PyObject_Str(op);
    else
        s = PyObject_Repr(op);
    ...
}
else
    ret = (*Py_TYPE(op)->tp_print)(op, fp, flags);

这意味着 __str____repr__ 只有在对象的类型没有 tp_print 函数时才会被调用。 tupleobject 有 one .

如果您想了解 CPython 的内部结构,最好的方法是阅读源代码。我在python internals上推荐一系列教程,它解释了您必须了解的所有内容,才能完全理解 python dis 函数的输出。

关于python - Python 2 使用什么方法打印元组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20716285/

相关文章:

python - 如何组织Python相关类

python-2.7 - redis:匹配散列的部分键

python - 在python中打印对象实例

c# - 从另一个类引用数据库上下文类

python - 使用 pyodbc 批量插入 + SQL Server 使用 None/Nan 很慢 + 解决方法

python - 如何将元素添加到 OrderedDict 的开头?

python - 一种在 Python 中连接字符串中的字符列表的优雅方法

python - 由几张Python Turtle图片组成的电影

c++ - 引用C++宏中的类

python - 如何在 Python 中获取当前脚本的代码?