Ich fühle mich verpflichtet darauf hinzuweisen, dass die Methode verwendet
signal(SIGPIPE, SIG_DFL)
ist in der Tat gefährlich (wie bereits von David Bennet in den Kommentaren vorgeschlagen) und führte in meinem Fall in Kombination mit plattformabhängigen lustigen Geschäften multiprocessing.Manager
(da die Standardbibliothek darauf beruht, dass BrokenPipeError an mehreren Stellen ausgelöst wird). Um es kurz und schmerzhaft zu machen: So habe ich es behoben:
Zuerst müssen Sie IOError
(Python 2) oder BrokenPipeError
(Python 3) fangen . Abhängig von Ihrem Programm können Sie versuchen, an diesem Punkt vorzeitig zu beenden oder die Ausnahme einfach zu ignorieren:
from errno import EPIPE
try:
broken_pipe_exception = BrokenPipeError
except NameError: # Python 2
broken_pipe_exception = IOError
try:
YOUR CODE GOES HERE
except broken_pipe_exception as exc:
if broken_pipe_exception == IOError:
if exc.errno != EPIPE:
raise
Dies ist jedoch nicht genug. Python 3 druckt möglicherweise immer noch eine Nachricht wie folgt:
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
Leider ist es nicht einfach, diese Nachricht loszuwerden, aber ich habe schließlich http://bugs.python.org/issue11380 gefunden, wo Robert Collins diese Problemumgehung vorschlägt, mit der ich mich in einen Dekorateur verwandelt habe, mit dem Sie Ihre Hauptfunktion abschließen können (ja, das ist verrückt Vertiefung):
from functools import wraps
from sys import exit, stderr, stdout
from traceback import print_exc
def suppress_broken_pipe_msg(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except SystemExit:
raise
except:
print_exc()
exit(1)
finally:
try:
stdout.flush()
finally:
try:
stdout.close()
finally:
try:
stderr.flush()
finally:
stderr.close()
return wrapper
@suppress_broken_pipe_msg
def main():
YOUR CODE GOES HERE
print(f1.readlines())