在没有打印功能的情况下显示数据时,IPython 和 REPL 的行为不同

cs9*_*s95 4 python ipython python-3.x read-eval-print-loop

请注意,所有实验均在 Python3.4.3 和 IPython 5.1.0(针对 python3)上进行。


考虑一个返回身份的函数:

def my_func(): 
    return 1
Run Code Online (Sandbox Code Playgroud)

现在,该函数是从 REPL 会话内的循环中调用的。

for _ in range(3): 
    my_func()
Run Code Online (Sandbox Code Playgroud)

在 IPython 上,什么也没有显示。

In [96]: for _ in range(3): 
    ...:     my_func()
    ...:     

In [97]: 
Run Code Online (Sandbox Code Playgroud)

但是,在 REPL 上,有一些事情是:

>>> for _ in range(3): 
...     my_func()
... 
1
1
1
>>>
Run Code Online (Sandbox Code Playgroud)

为什么会有差异?

是因为 IPython 做了什么吗?我检查了字节码,无论哪种情况,它们都是相同的。因此,它与字节码生成无关,而与两种情况下如何解释字节码有关。

use*_*ica 5

对于它的工作原理, IPython 在mode 而不是 中编译循环'exec''single',因此sys.displayhook循环内的表达式语句不会被触发。常规交互式解释器会执行您在'single'模式下输入的任何内容。'single'mode 是表达式语句触发的模式sys.displayhook

对于 IPython 这样做的原因,常规的 Python 行为是烦人多于有用。您很少想在循环中自动打印表达式语句的值;更常见的是,它会意外发生并将您感兴趣的内容滚动到屏幕之外。

IPython 尝试提供更有用的行为。显式打印您想要打印的内容比显式抑制您不想打印的内容直观得多。

  • @cᴏʟᴅsᴘᴇᴇᴅ:嗯,不是真正的模式。更重要的是您根本编译了该字符串。如果您将字符串传递给 Python 2 上的“dis.dis”,它会假定该字符串是字节码,而不是源代码。当你编译它时,你会得到一个代码对象,这是一个“dis.dis”知道如何反汇编的类型。(在 Python 3 上,“dis.dis”知道如何反汇编源代码,部分原因是源代码现在是 unicode 而字节码是 bytes。) (2认同)