如何在python中关闭文件描述符?

时间:2016-04-15 12:43:44

标签: python-2.7 file unix stdout

我在python中有以下代码:

import os


class suppress_stdout_stderr(object):
    '''
    A context manager for doing a "deep suppression" of stdout and stderr in
    Python, i.e. will suppress all print, even if the print originates in a
    compiled C/Fortran sub-function.
       This will not suppress raised exceptions, since exceptions are printed
    to stderr just before a script exits, and after the context manager has
    exited (at least, I think that is why it lets exceptions through).

    '''
    def __init__(self):
        # Open a pair of null files
        self.null_fds = [os.open(os.devnull,os.O_RDWR) for x in range(2)]
        # Save the actual stdout (1) and stderr (2) file descriptors.
        self.save_fds = (os.dup(1), os.dup(2))

    def __enter__(self):
        # Assign the null pointers to stdout and stderr.
        os.dup2(self.null_fds[0],1)
        os.dup2(self.null_fds[1],2)

    def __exit__(self, *_):
        # Re-assign the real stdout/stderr back to (1) and (2)
        os.dup2(self.save_fds[0],1)
        os.dup2(self.save_fds[1],2)
        # Close the null files
        os.close(self.null_fds[0])
        os.close(self.null_fds[1])

for i in range(10**6):
    with suppress_stdout_stderr():
        print 'plop'
    if i % 50 == 0:
        print i

在OSX上使用OSError: [Errno 24] Too many open files在5100处失败。我想知道为什么以及是否有解决方案来关闭文件描述符。我正在寻找关闭stdout和stderr的上下文管理器的解决方案。

1 个答案:

答案 0 :(得分:2)

我在Linux机器上执行了您的代码,并且在不同的迭代次数下得到了相同的错误。 我在您班级的__exit__(self, *_)函数中添加了以下两行:

os.close(self.save_fds[0]) os.close(self.save_fds[1])

通过此更改,我没有收到错误,脚本成功返回。我假设self.save_fds中存储的重复文件描述符保持打开状态,如果你不用os.close(fds)关闭它们,那么你会得到太多的文件打开错误。 无论如何我的控制台打印“plop”,但也许这取决于我的平台。 让我知道它是否有效:))