为什么在打印语句时会出现IOError: (9, 'Bad file descriptor')错误?

22

我正在一个Windows 2003服务器上以服务的形式运行一个Python2.5脚本。对于简单的打印语句,我遇到了以下错误:

IOError: (9, 'Bad file descriptor')

我删除了所有的打印语句,因为它们只是用于开发目的,但我不确定为什么打印语句会给我带来麻烦。我以非服务方式运行了相同的脚本,没有遇到任何重大问题。只是想知道是否有人有任何见解?

2个回答

31

当不运行控制台会话时,sys.stdout 不可用,因此无法打印。

可以考虑使用 logging 模块代替 print 语句,这样可以设置日志级别并将所有关键信息写入系统事件日志。


值得注意的是,您仍然可以通过执行以下操作来使其正常工作(或静默忽略该问题):

要按每个输出流写入文件:

import sys
sys.stdout = open('stdout.txt', 'w')
sys.stderr = open('stderr.txt', 'w')

写入单个文件:

import sys
sys.stdout = sys.stderr = open('output.txt', 'w')

或者默默地忽略所有的打印语句:

import sys
class NullWriter(object):
    def write(self, value): pass

sys.stdout = sys.stderr = NullWriter()

7
具体来说,如果您的程序不在控制台中运行,则前三个文件描述符(对应于stdin、stdout和stderr)将不可用。 - Ignacio Vazquez-Abrams
2
另一种忽略所有打印语句的方法是:sys.stdout = open(os.devnull, 'w') - Brendan Abel
1
这个解决了我的问题。你知道为什么只有在某些打印调用之后,已经忽略了一系列的调用,才会出现这种情况吗?也就是说,在一个无窗口运行的脚本中,它可以在执行到一半(其中包括很多print调用)之前失败,总是在同一个打印调用处,出现这个错误。 - SuperBiasedMan

5
在Python 2.x中,这是预期的行为。在此错误报告中,Christian Heimes解释了这是一种设计决策:

我建议不要在Python 2.7发布周期如此之晚更改代码。行为的变化太令人困惑。而且这并不是一个错误,而是一个设计决策。五年多以前,我为Python 3.0实现了部分与操作系统的IO交互。我有意没有将修改移植到2.6。

他还建议一种解决方案,以在Python 2.7中获得类似于Python 3.x的print()行为:
from __future__ import print_function
import sys
if sys.executable.endswith("pythonw.exe"):
    sys.stdout = sys.stdout = None

print("can handle sys.stdout = None just fine.")

Derrick,关于这个答案存在一些争议。经验丰富的用户们努力维护着本站信息的高质量,并标记此答案只包含指向外部网站的链接。我们倾向于不鼓励此类回答,因为链接可能会失效,这将使答案变得无用。这就是为什么它被踩了,也是为什么有多个删除投票针对它的原因。然而,我确实看到了你提供的链接的价值,并认为删除这个答案并不是适当的解决方案。 - Cody Gray
相反,我和另一个用户已经将链接中的相关信息编辑到了你的答案中。这应该有助于避免答案被删除,并可能为您赢得更多的赞。由于您是新用户,很抱歉您在该网站上有不好的体验。在未来发布答案时,请尽量记住好的答案完全是自包含的。最好的做法就是像我在这里所做的那样,将相关信息编辑到答案中,仅将链接作为补充。无论如何,只是想解释一下这个有趣的事情。祝你好运! - Cody Gray
谢谢您的更新。我仍然无法确定是否认为它是一个错误。在我的看法中,打印语句是事实上的调试工具,因此如此简单的东西几乎永远不应该失败。在您的编辑中有一行代码:“sys.stdout = sys.stdout = None”; 这应该改为“sys.stdout = sys.stderr = None”吗? - Derrick
我只是从链接的错误报告中Christian的帖子中完全复制了代码。你可能是对的,我真的不知道。老实说,我对Python一无所知,我只是为了帮助解决答案质量问题而加入。我认为这个答案没有必要被删除。 - Cody Gray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接