【问题标题】:How to understand sys.stdout and sys.stderr in Python如何理解 Python 中的 sys.stdout 和 sys.stderr
【发布时间】:2015-07-15 02:05:23
【问题描述】:

我有以下简单的 Python 代码。

stdout = sys.stdout
stderr = sys.stderr

try:
   # Omitted

finally:
  sys.stdout = stdout

搜索后发现sys.stdinsys.stdoutsys.stderr都是解释器的@对应的文件对象987654321@、standard outputstandard error 流。所以,我的猜测是,我们首先将 sys.stdoutsys.stderr 分配给变量 stdoutstderr em>。

那么,即使 try 语句中存在异常,我们是否总能取回 sys.stdout 呢?它是否正确?我觉得我还是一头雾水。

【问题讨论】:

  • 不管发生在什么情况下?不清楚你在问什么或试图完成什么

标签: python


【解决方案1】:

在普通的 C 程序中,默认打开三个“文件”:stdin、stdout 和 stderr。当您在 C 中进行输入和输出时,默认情况下它们来自标准输入和标准输出。但是,您也可以在代码需要文件的地方使用它们,或者将它们重新分配为新文件。

Python 试图“模仿”C 的这种行为。当您在 Python 中 print() 时,您的文本将写入 Python 的 sys.stdout。当您执行input() 时,它来自sys.stdin。异常写入sys.stderr

您可以重新分配这些变量,以便将代码的输出重定向到 stdout 以外的文件。这与shell redirection 非常相似,如果您熟悉的话。您可能会这样做的原因是保留程序输出的日志或使代码“关闭”,即不将输出发送到标准输出。因此,在您的示例中:

stdout = sys.stdout

try:
    sys.stdout = open('file.txt', 'w')
    print('blah')
    # etc
finally:
    sys.stdout.close()  # close file.txt
    sys.stdout = stdout
    sys.stderr = stderr

此代码不会向控制台打印任何内容,但会将“blah”写入名为file.txt 的文本文件。为了使这类事情不易出错,Python 提供了sys.__stdin__sys.__stdout__,它们始终保存sys.stdinsys.stdout 的原始值。使用以下代码可以使上面的代码更简单:

try:
    sys.stdout = open('file.txt', 'w')
    print('blah')
    # etc
finally:
    sys.stdout.close()  # close file.txt
    sys.stdout = sys.__stdout__

Python 之所以同时拥有stdout__stdout__ 主要是为了方便,所以你不必创建变量来备份stdout

但是,我必须建议您不要养成重新分配 stdout 的习惯。这样很容易把事情搞砸!如果要保存代码的输出,可以使用 shell 重定向。如果您希望能够记录程序正在执行的操作,请参阅 Python 的 logging 模块。如果你想让你的代码更安静,给你的函数一个quiet=False参数,这样你就可以在你想要的时候关闭它们!很少有“真正的”需要重新分配stdout 等。Python 允许您这样做,因为 Python 为程序员提供了很多控制权,并希望他们负责。如果你真的想这样做,你可以这样做:

>>> import random
>>> random.random = lambda: 1
>>> random.random()
1
>>> random.random()
1

【讨论】:

  • 那么,python中的'sys.stdin'和'sys._stdin'有什么区别呢?
  • 我用更多信息更新了很多答案。我不小心给了你不好的信息......它是__stdout__,而不是_stdout!此外,不同之处在于print() 使用stdout,而__stdout__ 是作为备份,以防您“丢失”原始值。
  • 帮助我了解何时将内容写入屏幕。你说“异常被写入 sys.stderr。”。但是,当我的代码崩溃时,它总是会打印到终端……这是否意味着向终端显示来自sys.errsys.stdout 的内容联合?
猜你喜欢
  • 2019-11-23
  • 2016-05-13
  • 2016-05-29
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 2013-07-10
相关资源
最近更新 更多