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

4

I have the following code in 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上,出现了5100错误,错误提示为OSError: [Errno 24] Too many open files。我想知道为什么会出现这个错误,以及是否有关闭文件描述符的解决方案。我正在寻找一个可以关闭stdout和stderr的上下文管理器的解决方案。


通常情况下,人们会使用 f = open(...); f.close() - Byte Commander
1个回答

8
我在Linux机器上执行了你的代码,得到了相同的错误,但是迭代次数不同。 我在你的类的__exit__(self, *_)函数中添加了以下两行代码: os.close(self.save_fds[0]) os.close(self.save_fds[1]) 这样改变后,我就没有再遇到错误了,脚本也成功返回。我猜想,如果你不用os.close(fds)关闭存储在self.save_fds中的重复文件描述符,则会保持这些文件描述符的打开状态,从而导致“文件打开过多”的错误。 不管怎样,我的控制台上打印出了“plop”,但这可能取决于我的平台。 如果可以,请告诉我它是否有效 :)

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