为什么 Python IDLE 将 None 回显为空而不是字符串 'None'(repr(None) 的值)?
Why does Python IDLE echo None as empty instead of string 'None' (the value of repr(None))?
根据 official doc,“repr
函数用于表达式值的交互式回显”。
基本上,你在echo中看到的就相当于print(repr(*yourexpression*)
.
这似乎在大多数情况下都是正确的,但 None
是例外。
>>> print(repr(1))
1
>>> 1
1
>>> print(repr('abc'))
'abc'
>>> 'abc'
'abc'
>>> print(repr(None))
None
>>> None
>>>
read-eval-print-loop 或 REPL 通常只打印非 None
结果。这可以防止它阻塞你的函数输出,但除此之外 return 什么都没有。
这种自动输出结果是 REPL 独有的,这不是 Python 在正常业务过程中所做的事情(例如,当 运行 脚本时)。
实际使用的方法结合了交互模式下发生的一些事情。首先,在编译时,正常的 POP_TOP
操作码(旨在简单地删除结果)在最顶层被替换为 PRINT_EXPR
(与直接问题无关的代码,在下面的所有代码片段中,已被删除, 代码也可能被重新格式化了一点):
static int compiler_visit_stmt_expr(struct compiler *c, expr_ty value) {
if (c->c_interactive && c->c_nestlevel <= 1) {
VISIT(c, expr, value);
ADDOP(c, PRINT_EXPR);
return 1;
}
VISIT(c, expr, value);
ADDOP(c, POP_TOP);
return 1;
}
其次,在解释时,sys.displayhook
对象,一个旨在以交互模式显示结果的函数,通常指向一个函数,该函数只会打印出不是 None
的值。在处理上述PRINT_EXPR
操作码时在ceval
代码中调用:
case TARGET(PRINT_EXPR): {
PyObject *value = POP();
PyObject *hook = _PySys_GetObjectId(&PyId_displayhook);
res = PyObject_CallOneArg(hook, value);
}
default 挂钩看起来像这样,如果值为 None
:[=23=,您可以简单地看到它 returns 而没有输出]
static PyObject *sys_displayhook(PyObject *module, PyObject *o) {
if (o == Py_None) {
Py_RETURN_NONE;
}
if (PyFile_WriteObject(o, outf, 0) != 0) {
return NULL;
}
Py_RETURN_NONE;
}
这个挂钩实际上允许您根据需要更改默认行为,尽管下面的 FortyTwo
示例有点,呃...,不太有用:
>>> 1
1
>>> None
>>> def NonesAsWell(x):
... print(x)
...
>>> sys.displayhook = NonesAsWell
>>> 1
1
>>> None
None
>>> def FortyTwo(x):
... print(42)
...
>>> sys.displayhook = FortyTwo
>>> 1
42
>>> None
42
字面问题“为什么 IDLE Shell 在用户输入语句时显示它的作用?”的答案。除了少数例外,IDLE Shell 旨在显示与 Python REPL 相同的输出。对于此处讨论的条目,确实如此。
其他人已经回答了基本问题“为什么 Python REPL 会做它做的事情。”
根据 official doc,“repr
函数用于表达式值的交互式回显”。
基本上,你在echo中看到的就相当于print(repr(*yourexpression*)
.
这似乎在大多数情况下都是正确的,但 None
是例外。
>>> print(repr(1))
1
>>> 1
1
>>> print(repr('abc'))
'abc'
>>> 'abc'
'abc'
>>> print(repr(None))
None
>>> None
>>>
read-eval-print-loop 或 REPL 通常只打印非 None
结果。这可以防止它阻塞你的函数输出,但除此之外 return 什么都没有。
这种自动输出结果是 REPL 独有的,这不是 Python 在正常业务过程中所做的事情(例如,当 运行 脚本时)。
实际使用的方法结合了交互模式下发生的一些事情。首先,在编译时,正常的 POP_TOP
操作码(旨在简单地删除结果)在最顶层被替换为 PRINT_EXPR
(与直接问题无关的代码,在下面的所有代码片段中,已被删除, 代码也可能被重新格式化了一点):
static int compiler_visit_stmt_expr(struct compiler *c, expr_ty value) {
if (c->c_interactive && c->c_nestlevel <= 1) {
VISIT(c, expr, value);
ADDOP(c, PRINT_EXPR);
return 1;
}
VISIT(c, expr, value);
ADDOP(c, POP_TOP);
return 1;
}
其次,在解释时,sys.displayhook
对象,一个旨在以交互模式显示结果的函数,通常指向一个函数,该函数只会打印出不是 None
的值。在处理上述PRINT_EXPR
操作码时在ceval
代码中调用:
case TARGET(PRINT_EXPR): {
PyObject *value = POP();
PyObject *hook = _PySys_GetObjectId(&PyId_displayhook);
res = PyObject_CallOneArg(hook, value);
}
default 挂钩看起来像这样,如果值为 None
:[=23=,您可以简单地看到它 returns 而没有输出]
static PyObject *sys_displayhook(PyObject *module, PyObject *o) {
if (o == Py_None) {
Py_RETURN_NONE;
}
if (PyFile_WriteObject(o, outf, 0) != 0) {
return NULL;
}
Py_RETURN_NONE;
}
这个挂钩实际上允许您根据需要更改默认行为,尽管下面的 FortyTwo
示例有点,呃...,不太有用:
>>> 1
1
>>> None
>>> def NonesAsWell(x):
... print(x)
...
>>> sys.displayhook = NonesAsWell
>>> 1
1
>>> None
None
>>> def FortyTwo(x):
... print(42)
...
>>> sys.displayhook = FortyTwo
>>> 1
42
>>> None
42
字面问题“为什么 IDLE Shell 在用户输入语句时显示它的作用?”的答案。除了少数例外,IDLE Shell 旨在显示与 Python REPL 相同的输出。对于此处讨论的条目,确实如此。
其他人已经回答了基本问题“为什么 Python REPL 会做它做的事情。”