Saya merasa berkewajiban untuk menunjukkan bahwa metode yang digunakan
signal(SIGPIPE, SIG_DFL)
memang berbahaya (seperti yang sudah disarankan oleh David Bennet di komentar) dan dalam kasus saya menyebabkan bisnis lucu yang bergantung pada platform bila digabungkan dengan multiprocessing.Manager
(karena pustaka standar bergantung pada BrokenPipeError yang dimunculkan di beberapa tempat). Singkatnya, begini cara saya memperbaikinya:
Pertama, Anda perlu menangkap IOError
(Python 2) atau BrokenPipeError
(Python 3). Bergantung pada program Anda, Anda dapat mencoba keluar lebih awal pada saat itu atau mengabaikan pengecualian:
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
Namun, ini belum cukup. Python 3 masih dapat mencetak pesan seperti ini:
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
Sayangnya menghilangkan pesan itu tidak langsung, tetapi akhirnya saya menemukan http://bugs.python.org/issue11380 di mana Robert Collins menyarankan solusi ini yang saya ubah menjadi dekorator yang dapat Anda bungkus dengan fungsi utama Anda (ya, itu gila lekukan):
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())