2016-04-15 6 views
1

Ich habe den folgenden Code in Python:Wie schließe ich Dateideskriptoren 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 

es bei 5100 auf OSX mit OSError: [Errno 24] Too many open files ausfällt. Ich frage mich, warum und ob es eine Lösung gibt, um den Dateideskriptor zu schließen. Ich suche nach einer Lösung für einen Kontextmanager, der stdout und stderr schließt.

+0

Normalerweise würde man 'f = open (...); f.close() '. –

Antwort

2

Ich habe Ihren Code auf einer Linux-Maschine ausgeführt und den gleichen Fehler erhalten, aber bei einer anderen Anzahl von Iterationen. Ich habe die folgenden zwei Zeilen in der __exit__(self, *_) Funktion Ihrer Klasse:

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

Mit dieser Änderung erhalte ich keinen Fehler und das Skript erfolgreich zurückgegeben. Ich nehme an, dass die duplizierten Dateideskriptoren, die in self.save_fds gespeichert sind, offen bleiben, wenn Sie sie nicht mit os.close(fds) schließen, und so erhalten Sie den Fehler zu viele Dateien öffnen. Wie auch immer, meine Konsole druckte "plop", aber vielleicht hängt das von meiner Plattform ab. Lass es mich wissen, wenn es funktioniert :)

Verwandte Themen