2016-04-15 84 views
1

我有蟒蛇以下代码:如何在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 

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

+0

通常会使用'f = open(...); f.close()'。 –

回答

2

我在Linux机器上执行了你的代码,并得到了相同的错误,但是迭代次数不同。 添加以下两行类的__exit__(self, *_)功能:

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

有了这个变化我没有得到一个错误,而且脚本成功返回。我假设如果你不用os.close(fds)关闭它们,保存在self.save_fds中的重复文件描述符就会保持打开状态,所以你会得到太多的文件打开错误。 无论如何,我的控制台打印“plop”,但也许这取决于我的平台。 让我知道它是否有效:)

相关问题