0

大量のデータを生成する外部プログラム (サードパーティ、私はそれを制御できません) によって生成された出力を解析する必要があります。出力のサイズが使用可能なメモリを大幅に超えているため、プロセスの実行中に出力を解析し、既に処理されたデータをメモリから削除したいと考えています。

これまでのところ、私は次のようなことをしています:

import subprocess

p_pre = subprocess.Popen("preprocessor",stdout = subprocess.PIPE) 
# preprocessor is an external bash script that produces the input for the third-party software
p_3party = subprocess.Popen("thirdparty",stdin = p_pre.stdout, stdout = subprocess.PIPE)

(data_to_parse,can_be_thrown) = p_3party.communicate()

parsed_data = myparser(data_to_parse)

「サードパーティ」の出力が十分に小さい場合、このアプローチは機能します。しかし、Pythonのドキュメントに記載されているように:

読み取ったデータはメモリにバッファリングされるため、データ サイズが大きい場合や無制限の場合は、このメソッドを使用しないでください。

より良いアプローチ (実際に時間を節約できる可能性があります)data_to_parseは、生成中に処理を開始し、解析が正しく行われたときに、data_to_parse既に解析されたデータを削除して「クリア」することだと思います。

また、次のような for サイクルを使用しようとしました。

parsed_data=[]
for i in p_3party.stdout:
    parsed_data.append(myparser(i))

しかし、行き詰まり、その理由を理解できません。

それで、これを達成するための最良のアプローチは何ですか?知っておくべき問題は何ですか?

4

2 に答える 2

1

subprocess.Popen() を使用して、行を読み取るストリームを作成できます。

import subprocess

stream = subprocess.Popen(stdout=subprocess.PIPE).stdout

for line in stream:
    #parse lines as you recieve them.
    print line

行をメソッドに渡すmyparser()か、使用する準備が整うまでリストに追加することができます..何でも。


あなたの場合、2 つのサブプロセスを使用すると、次のように機能します。

import subprocess

def method(stream, retries=3):
    while retries > 0:
        line = stream.readline()
        if line:
            yield line
        else:
            retries -= 1

pre_stream = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
stream = subprocess.Popen(cmd, stdin=pre_stream, stdout=subprocess.PIPE).stdout

for parsed in method(stream):
    # do what you want with the parsed data.
    parsed_data.append(parsed)
于 2013-04-03T11:38:17.730 に答える
1

のようにファイルを反復処理すると、for i in p_3party.stdout:先読みバッファが使用されます。メソッドはパイプを使用readline()するとより信頼性が高くなる可能性があります-AFAIKは文字ごとに読み取ります。

while True:
    line = p_3party.stdout.readline()
    if not line:
        break
    parsed_data.append(myparser(line))
于 2013-04-03T11:51:46.623 に答える