2

csv ファイルを読み込んでいるときに、自分がいる場所の割合を見つけようとしています。ファイルオブジェクトでtell()を使用してこれを行う方法は知っていますが、csv.readerを使用してそのファイルオブジェクトを読み取り、リーダーオブジェクトの行に対してforループを実行すると、tell()関数は常に次のように戻りますループのどこにいても、ファイルの最後にあります。今いる場所を見つけるにはどうすればよいですか?

現在のコード:

with open(FILE_PERSON, 'rb') as csvfile:
    spamreader = csv.reader(csvfile)
    justtesting = csvfile.tell()
    size = os.fstat(csvfile.fileno()).st_size
    for row in spamreader:
        pos = csvfile.tell()
        print pos, "of", size, "|", justtesting

for ループを開始するまで tell() が 0 を返すことを証明するために、そこに「justtesting」を挿入しました。

これにより、csv ファイルのすべての行に対して同じ結果が返されます: 579 of 579 | 0

私は何を間違っていますか?

4

2 に答える 2

0

csvreaderドキュメントは言う:

... csvfile は、反復子プロトコルをサポートし、 next() メソッドが呼び出されるたびに文字列を返す任意のオブジェクトにすることができます ...

したがって、OP の元のコードに小さな変更を加えます。

import csv
import os
filename = "tar.data"
with open(filename, 'rb') as csvfile:
    spamreader = csv.reader(csvfile)
    justtesting = csvfile.tell()
    size = os.fstat(csvfile.fileno()).st_size
    for row in spamreader:
        pos = csvfile.tell()
        print pos, "of", size, "|", justtesting
###############################################
def generator(csvfile):
    # readline seems to be the key
    while True:
        line = csvfile.readline()
        if not line:
            break
        yield line
###############################################
print
with open(filename, 'rb', 0) as csvfile:
    spamreader = csv.reader(generator(csvfile))
    justtesting = csvfile.tell()
    size = os.fstat(csvfile.fileno()).st_size
    for row in spamreader:
        pos = csvfile.tell()
        print pos, "of", size, "-", justtesting

これをテスト データに対して実行すると、次のようになります。2 つの異なるアプローチで異なる結果が得られることがわかります。

224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0
224 of 224 | 0

16 of 224 - 0
32 of 224 - 0
48 of 224 - 0
64 of 224 - 0
80 of 224 - 0
96 of 224 - 0
112 of 224 - 0
128 of 224 - 0
144 of 224 - 0
160 of 224 - 0
176 of 224 - 0
192 of 224 - 0
208 of 224 - 0
224 of 224 - 0

でバッファリングをゼロに設定しましたopenが、違いはありませんでした。問題readlineはジェネレータにあります。

于 2013-02-14T17:42:45.190 に答える