2016-04-15 12 views
1

私はPythonで、次のコードを持っている: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 

それはOSError: [Errno 24] Too many open filesとOSX上で5100で失敗します。私はなぜ、そしてファイル記述子を閉じる解決策があるのだろうかと思っています。私はstdoutとstderrを閉じるコンテキストマネージャのためのソリューションを探しています。

+0

通常、 'f = open(...);を使用します。 f.close() ' –

答えて

2

Linuxマシンでコードを実行したところ、同じエラーが発生しましたが、繰り返し回数が異なります。私はエラーを取得しないこの変更により

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

を、スクリプトが正常に返さ: 私はあなたのクラスの__exit__(self, *_)機能に次の2行を追加しました。あなたがos.close(fds)でそれらを閉じないと、開いているファイルのディスクリプタがself.save_fdsに保存されていると思います。 とにかく私のコンソールは "plop"を印刷しましたが、おそらくこれは私のプラットフォームによって異なります。 動作しているかどうか教えてください:)

関連する問題