43

標準入力からCSVファイルを読み取り、各行を処理します。CSV出力コードは行を1つずつ書き込みますが、リーダーはストリームが終了するのを待ってから行を繰り返します。csvこれはモジュールの制限ですか?私は何か間違ったことをしていますか?

私のリーダーコード:

import csv
import sys
import time


reader = csv.reader(sys.stdin)
for row in reader:
    print "Read: (%s) %r" % (time.time(), row)

私のライターコード:

import csv
import sys
import time


writer = csv.writer(sys.stdout)
for i in range(8):
    writer.writerow(["R%d" % i, "$" * (i+1)])
    sys.stdout.flush()
    time.sleep(0.5)

の出力python test_writer.py | python test_reader.py

Read: (1309597426.3) ['R0', '$']
Read: (1309597426.3) ['R1', '$$']
Read: (1309597426.3) ['R2', '$$$']
Read: (1309597426.3) ['R3', '$$$$']
Read: (1309597426.3) ['R4', '$$$$$']
Read: (1309597426.3) ['R5', '$$$$$$']
Read: (1309597426.3) ['R6', '$$$$$$$']
Read: (1309597426.3) ['R7', '$$$$$$$$']

ご覧のとおり、すべてのprintステートメントが同時に実行されますが、500ミリ秒のギャップがあると思います。

4

3 に答える 3

47

ドキュメントに記載されているように、

forループをファイルの行をループする最も効率的な方法(非常に一般的な操作)にするために、このメソッドnext()は非表示の先読みバッファーを使用します。

そして、基礎となるイテレータのメソッドを呼び出すモジュール(784行目)の実装をcsv見るとわかります(via )。csv.readernext()PyIter_Next

したがって、CSVファイルのバッファなしの読み取りが本当に必要な場合は、ファイルオブジェクト(ここ)を、代わりにメソッドが実際に呼び出すsys.stdinイテレータに変換する必要があります。これは、関数の2つの引数形式を使用して簡単に実行できます。したがって、コードを次のようなものに変更します。next()readline()itertest_reader.py

for row in csv.reader(iter(sys.stdin.readline, '')):
    print("Read: ({}) {!r}".format(time.time(), row))

例えば、

$ python test_writer.py | python test_reader.py
Read: (1388776652.964925) ['R0', '$']
Read: (1388776653.466134) ['R1', '$$']
Read: (1388776653.967327) ['R2', '$$$']
Read: (1388776654.468532) ['R3', '$$$$']
[etc]

CSVファイルのバッファなしの読み取りが必要な理由を説明できますか?あなたがやろうとしていることが何であれ、より良い解決策があるかもしれません。

于 2011-07-02T12:01:20.843 に答える
1

多分それは制限です。これを読んでくださいhttp://docs.python.org/using/cmdline.html#cmdoption-unittest-discover-u

file.readlines()およびファイルオブジェクト(sys.stdinの行用)には、このオプションの影響を受けない内部バッファリングがあることに注意してください。これを回避するには、while 1:ループ内でfile.readline()を使用する必要があります。

test_reader.pyを次のように変更しました:

import csv, sys, time

while True:
    print "Read: (%s) %r" % (time.time(), sys.stdin.readline())

出力

python test_writer.py | python  test_reader.py
Read: (1309600865.84) 'R0,$\r\n'
Read: (1309600865.84) 'R1,$$\r\n'
Read: (1309600866.34) 'R2,$$$\r\n'
Read: (1309600866.84) 'R3,$$$$\r\n'
Read: (1309600867.34) 'R4,$$$$$\r\n'
Read: (1309600867.84) 'R5,$$$$$$\r\n'
Read: (1309600868.34) 'R6,$$$$$$$\r\n'
Read: (1309600868.84) 'R7,$$$$$$$$\r\n'
于 2011-07-02T10:02:45.590 に答える
0

stdoutをフラッシュしていますが、stdinはフラッシュしていません。

Sys.stdin方法もありflush()ます。本当にバッファリングを無効にしたい場合は、各行を読み取った後にそれを使用してみてください。

于 2011-07-02T09:32:59.753 に答える