私はそれを使用する方法を指摘する義務を感じます
signal(SIGPIPE, SIG_DFL)
確かに危険であり(David Bennetがコメントですでに示唆しているように)、私の場合、組み合わせたときにプラットフォーム依存の面白いビジネスにつながりましたmultiprocessing.Manager
(標準ライブラリはBrokenPipeErrorがいくつかの場所で発生することに依存しているため)。長くてつらい話を短くするために、これは私がそれを修正した方法です:
まず、IOError
(Python 2)またはBrokenPipeError
(Python 3)をキャッチする必要があります。プログラムに応じて、その時点で早期に終了するか、例外を無視することができます。
from errno import EPIPE
try:
broken_pipe_exception = BrokenPipeError
except NameError:
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
ただし、これだけでは不十分です。Python 3でも、次のようなメッセージが出力される場合があります。
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
残念ながら、そのメッセージを取り除くのは簡単ではありませんが、最終的にhttp://bugs.python.org/issue11380を見つけました。ここで、Robert Collinsは、メイン関数をラップできるデコレータに変えたこの回避策を提案しています(はい、それはクレイジーです)インデント):
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())