如何理解python中的sys.stdout和sys.stderr

时间:2015-07-15 02:05:23

标签: python

我有以下简单的python代码。

stdout = sys.stdout
stderr = sys.stderr

try:
   # omited

finally:
  sys.stdout = stdout

搜索之后,我发现sys.stdin,sys.stdout和sys.stderr是与解释器的标准输入,标准输出和标准错误流相对应的文件对象。所以,我的猜测是我们首先将sys.stdout和sys.stderr分配给变量stdout和stderr。那么,即使try语句中有异常,我们也总是得到sys.stdout?它是否正确?我觉得我还是很困惑。非常感谢您的时间和关注。

1 个答案:

答案 0 :(得分:9)

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

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

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

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