在Python中进行冲洗时,如何防止BrokenPipeError? [英] How to prevent BrokenPipeError when doing a flush in Python?

查看:1132
本文介绍了在Python中进行冲洗时,如何防止BrokenPipeError?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:是否可以在 print()函数中使用 flush = True 而不获取< a href = https://docs.python.org/3/library/exceptions.html#BrokenPipeError rel = noreferrer> BrokenPipeError

Question: Is there a way to use flush=True for the print() function without getting the BrokenPipeError?

我有一个脚本 pipe.py

for i in range(4000):
    print(i)

我从Unix命令行这样称呼它:

I call it like this from a Unix command line:

python3 pipe.py | head -n3000

它返回:

0
1
2

这个脚本也是这样的:

import sys
for i in range(4000):
    print(i)
    sys.stdout.flush()

但是,当我运行此脚本和管道时到 head -n3000

However, when I run this script and pipe it to head -n3000:

for i in range(4000):
    print(i, flush=True)

然后我得到这个错误:

    print(i, flush=True)
BrokenPipeError: [Errno 32] Broken pipe
Exception BrokenPipeError: BrokenPipeError(32, 'Broken pipe') in <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> ignored

我也尝试了以下解决方案,但仍然得到 BrokenPipeError

I have also tried the solution below, but I still get the BrokenPipeError:

import sys
for i in range(4000):
    try:
        print(i, flush=True)
    except BrokenPipeError:
        sys.exit()


推荐答案

BrokenPipeError 像幻影一样正常,因为读取过程(头)终止并关闭其

The BrokenPipeError is normal as said phantom because the reading process (head) terminates and closes its end of the pipe while the writing process (python) still tries to write.

是异常情况,并且python脚本收到一个 BrokenPipeError -更确切地说,Python解释器收到系统SIGPIPE信号,该信号捕获并引发 BrokenPipeError 以允许脚本处理错误。

Is is an abnormal condition, and the python scripts receives a BrokenPipeError - more exactly, the Python interpreter receives a system SIGPIPE signal that it catches and raises the BrokenPipeError to allow the script to process the error.

您可以有效地处理错误,因为在上一个示例中,您仅看到一条消息,指出异常是ig nored-好的,这不是真的,但似乎与此Python中的公开问题有关:Python开发人员认为警告用户很重要

And you effectively can process the error, because in your last example, you only see a message saying that the exception was ignored - ok it is not true, but seems related to this open issue in Python : Python developpers think important to warn user of the abnormal condition.

真正发生的是,即使您捕获到异常,Python解释器AFAIK始终会在stderr上发出信号。但是,您只需要在退出前关闭stderr即可消除该消息。

What really happens is that AFAIK the python interpreter always signals this on stderr, even if you catch the exception. But you just have to close stderr before exiting to get rid of the message.

我将脚本略微更改为:


  • 像在上一个示例中一样捕获错误

  • 捕获IOError(我在Windows64上使用Python34)或BrokenPipeError(在Python 33上) FreeBSD 9.0)-并为此显示一条消息

  • 在stderr上显示一条自定义的 Done 消息(由于管道断开,stdout已关闭)
  • b $ b
  • 关闭stderr ,然后退出以摆脱消息

  • catch the error as you did in your last example
  • catch either IOError (that I get in Python34 on Windows64) or BrokenPipeError (in Python 33 on FreeBSD 9.0) - and display a message for that
  • display a custom Done message on stderr (stdout is closed due to the broken pipe)
  • close stderr before exiting to get rid of the message

以下是脚本我用过:

import sys

try:
    for i in range(4000):
            print(i, flush=True)
except (BrokenPipeError, IOError):
    print ('BrokenPipeError caught', file = sys.stderr)

print ('Done', file=sys.stderr)
sys.stderr.close()

这里是 python3.3 pipe.py的结果|头-10

0
1
2
3
4
5
6
7
8
9
BrokenPipeError caught
Done

如果您不希望收到无关的邮件,请使用:

If you do not want the extraneous messages just use :

import sys

try:
    for i in range(4000):
            print(i, flush=True)
except (BrokenPipeError, IOError):
    pass

sys.stderr.close()

这篇关于在Python中进行冲洗时,如何防止BrokenPipeError?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆