将进程替代作为Python的输入文件使用两次

3 投票
2 回答
556 浏览
提问于 2025-04-18 00:47

考虑下面这个Python脚本:

#test.py
import sys
inputfile=sys.argv[1]
with open(inputfile,'r') as f:
    for line in f.readlines():
        print line

with open(inputfile,'r') as f:
    for line in f.readlines():
        print line

现在我想在一个替代的进程中运行 test.py,比如:

python test.py <( cat file | head -10)

看起来第二个 f.readlines 返回的是空的。这是为什么呢?有没有办法在不指定两个输入文件的情况下做到这一点?

2 个回答

1

readlines() 这个函数会一次性读取输入的所有行。这就是为什么第二次调用它时没有返回任何内容,因为已经没有东西可以读取了。你可以把 readlines() 的结果存储到一个本地变量中,然后想用多少次就用多少次:

import sys
inputfile=sys.argv[1]
with open(inputfile,'r') as f:
    lines = f.readlines()
    for line in lines:
        print line

    #use it again
    for line in lines:
        print line
4
  • 为什么会这样呢?
    • 进程替换是通过创建一个命名管道来实现的。所以所有的数据都是在第一次打开/读取的时候被消耗掉的。
  • 有没有办法不需要指定两个输入文件呢?
    • 可以考虑在使用之前先对数据进行缓冲。

下面是一个示例代码

import sys
import StringIO
inputfile=sys.argv[1]

buffer = StringIO.StringIO()

# buffering
with open(inputfile, 'r') as f:
    buffer.write(f.read())

# use it 
buffer.seek(0)
for line in buffer:
    print line

# use it again
buffer.seek(0)
for line in buffer:
    print line

撰写回答