下面是我所看到的一个例子:

❯ cat /tmp/test.py
#!/usr/bin/env python3

import csv

with open("/dev/stdout", "w") as f:
    csvwriter = csv.writer(f)
    csvwriter.writerows((_,) for _ in range(10000))

当重定向到文件或发送到标准输出时,它运行得很好.

❯ /tmp/test.py > /dev/null
❯ echo $?
0

然而,当发送到Head以及其他一些工具时,它会引发异常.

❯ /tmp/test.py | head > /dev/null
Traceback (most recent call last):
  File "/tmp/test.py", line 7, in <module>
    csvwriter.writerows((_,) for _ in range(10000))
BrokenPipeError: [Errno 32] Broken pipe

During handling of the above exception, another exception occurred:

BrokenPipeError: [Errno 32] Broken pipe

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/test.py", line 5, in <module>
    with open("/dev/stdout", "w") as f:
BrokenPipeError: [Errno 32] Broken pipe

如果我有range(15)个左右,那就没问题.问题是,有没有一些我可以在Python中使用的设置来避免这种行为?

推荐答案

来自SIGPIPE(https://docs.python.org/3/library/signal.html#note-on-sigpipe)的python文档:

将程序的输出通过管道传输到HEAD(1)之类的工具,将导致在其标准输出的接收器提前关闭时向您的进程发送SIGPIPE信号.这会导致异常,如BrokenPipeError:[Errno 32]BREAKED PIPE.要处理这种情况,请按如下方式包装您的入口点以捕获此异常:

将它们的示例改编为您的代码,您可以像这样处理此异常:

import os, sys, csv

try:
    with open("/dev/stdout", "w") as f:
        csvwriter = csv.writer(f)
        csvwriter.writerows((_,) for _ in range(10000))
    sys.stdout.flush()
except BrokenPipeError:
    # Python flushes standard streams on exit; redirect remaining output
    # to devnull to avoid another BrokenPipeError at shutdown
    devnull = os.open(os.devnull, os.O_WRONLY)
    os.dup2(devnull, sys.stdout.fileno())
    sys.exit(1)  # Python exits with error code 1 on EPIPE

Python相关问答推荐

两极:滚动组,起始指数由不同列设置

如何将 map 数组组合到pyspark中每列的单个 map 中

删除pandas rame时间序列列中未更改的值

具有2D功能的Python十六进制图

Twilio:CallInstance对象没有来自_的属性'

DuckDB将蜂巢分区插入拼花文件

如何用symy更新分段函数

使用pandas、matplotlib和Yearbox绘制时显示错误的年份

pandas滚动和窗口中有效观察的最大数量

使用@ guardlasses. guardlass和注释的Python继承

在Python中动态计算范围

海上重叠直方图

使用Python更新字典中的值

将JSON对象转换为Dataframe

不允许访问非IPM文件夹

在matplotlib中删除子图之间的间隙_mosaic

matplotlib图中的复杂箭头形状

python中csv. Dictreader. fieldname的类型是什么?'

pysnmp—lextudio使用next()和getCmd()生成器导致TypeError:tuple对象不是迭代器''

用SymPy在Python中求解指数函数