【问题标题】:Different behaviours of printing strings (sys.stderr.write) in Jupyter Notebook and Linux terminalJupyter Notebook 和 Linux 终端中打印字符串 (sys.stderr.write) 的不同行为
【发布时间】:2018-07-04 08:07:13
【问题描述】:

在 Jupyter Notebook 中,运行以下 Python 代码时,会一个接一个地打印 2 到 9 的数字。 进口时间

for i in range(1,10):
    time.sleep(1)
    sys.stderr.write('\r %d' % i)
    sys.stderr.flush()

Q1:为什么没有打印1?

Q2:为什么一个接一个地打印数字,我的意思是,当打印一个较大的数字时,紧邻的较小数字会消失(这很棒)? 为什么sys.stderr.write('\r %d' % i)有效以这种方式,但sys.stderr.write('%d \r' % i) 以“正常”方式工作,显示所有数字?

在 Linux 终端中运行上述代码时。输出又不一样了:

 13
 23
 33
 43
 53
 63
 73
 83
 93

如果我将sys.stderr.write('\r %d' % i) 行更改为sys.stderr.write('%d \r' % i),则输出变为:

3 
3 
3 
3 
3 
3 
3 
3 
3

这太奇怪了。

Q3:为什么在Linux终端运行上述代码会有不同的输出?

【问题讨论】:

  • 我刚刚在 jupyter-notebook 中使用 Python3 内核尝试了您的代码,实际上 1 已打印出来。
  • @timgeb 好的,你是对的。我正在使用集成在 PyCharm 中的 Jupyter Notebook,可能有问题。我刚刚在基于网络的 Jupyter Notebook 上尝试了代码,它确实输出了 1。我将排除第一个问题。

标签: python string terminal jupyter-notebook jupyter


【解决方案1】:

Q1:为什么没有打印1?

它确实打印了。尝试更长的睡眠时间。

Q2:为什么一个接一个地打印数字,我的意思是,当打印一个较大的数字时,紧挨着的较小的数字会消失(这很棒)?

这是因为您使用的是回车符\r 而不是换行符\n,它将光标返回到行首,而不是将光标移到下一行。您还可以使用退格 \b 将光标移回一个空格来覆盖终端中的内容。

Q3:为什么在Linux终端运行上述代码会有不同的输出?

我不确定你指的是哪个终端。有些终端不支持覆盖,所以你刷新的顺序会影响输出。

另外,查看write 方法的文档字符串,

idlelib.run.PseudoOutputFile 实例的 write(s) 方法 将字符串写入流。 返回写入的字符数(始终等于 字符串的长度)。

它返回您传入的字符串的长度。在 Python shell (REPL) 中,所有返回值都会在函数返回后打印出来。在 IDLE 中试试这个,其中 stdin 和 stderr 以不同的颜色打印:

>>> sys.stderr.write('x')

但是看看如果你在终端中运行它会发生什么,

>>> sys.stdout.write('abc\r')
4bc

首先打印abc,然后将光标返回到行首。然后它返回 4,因为字符串的长度为 4,所以 Python 的 REPL 会在光标的当前位置打印它,覆盖 a

【讨论】:

  • 对于 Ubuntu 终端中的 Q3,在打印时总是在每个数字后面附加一个特殊数字。似乎特殊数字取决于\r%d 之间有多少空格。没有空格时,1个空格,2个空格,特殊数字为2,3,4。
猜你喜欢
  • 2021-03-07
  • 2021-05-23
  • 2016-02-07
  • 2022-12-24
  • 2016-12-06
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
相关资源
最近更新 更多