我可以在Python中用Popen处理已打开的gzip文件吗?

6 投票
1 回答
1521 浏览
提问于 2025-04-15 22:08

我有一个小工具,可以在命令行中使用,它会从标准输入(stdin)读取数据。

在命令行中,我可以这样运行它...

./foo < bar

或者这样...

cat bar | ./foo

如果我有一个压缩过的文件,我可以这样运行它

zcat bar.gz | ./foo

在Python中,我可以这样做...

Popen(["./foo", ], stdin=open('bar'), stdout=PIPE, stderr=PIPE)

但是我不能这样做

import gzip
Popen(["./foo", ], stdin=gzip.open('bar'), stdout=PIPE, stderr=PIPE)

结果我不得不这样运行

p0 = Popen(["zcat", "bar"], stdout=PIPE, stderr=PIPE)
Popen(["./foo", ], stdin=p0.stdout, stdout=PIPE, stderr=PIPE)

我是不是做错了什么?为什么我不能把gzip.open('bar')作为Popen的标准输入参数?

1 个回答

4

因为子进程的'标准输入'和'标准输出'使用的是文件描述符(这其实就是一个数字),它是操作系统的一种资源。这个过程有点复杂,因为如果你传递一个对象,子进程模块会检查这个对象是否有'fileno'这个属性,如果有,它就会使用这个属性。

'gzip'对象并不是操作系统提供的东西。打开的文件、套接字和管道都是操作系统能提供的资源。而gzip对象是一个提供read()和write()方法的对象,但它没有'fileno'这个属性。

不过,你可以看看子进程的communicate()方法,你可能会想用到它。

撰写回答