我有以下简单的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?它是否正确?我觉得我还是很困惑。非常感谢您的时间和关注。
答案 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.stdin
和sys.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