Python3でファイルを反復処理するときにファイルカーソルの位置を知るにはどうすればよいですか?Python3でファイルの行を繰り返し処理しているときに `tell()`を実行する代わりに?
Python 2.7でそれは簡単です、tell()
を使用してください。 python3で同じコールがOSError
を投げること:
Traceback (most recent call last):
File "foo.py", line 113, in check_file
pos = infile.tell()
OSError: telling position disabled by next() call
私のユースケースは、大きなCSVファイルを読み込むためのプログレスバーを作っています。総ライン数を計算するには高価すぎるため、余分なパスが必要です。おおよその値は十分ですが、バッファやその他のノイズ源は気にしません。10秒か10分かかりますか?
問題を再現するための簡単なコード。これは、予想通りのPython 2.7では動作するのですが、Pythonの3にスロー:
file_size = os.stat(path).st_size
with open(path, "r") as infile:
reader = csv.reader(infile)
for row in reader:
pos = infile.tell() # OSError: telling position disabled by next() call
print("At byte {} of {}".format(pos, file_size))
この回答https://stackoverflow.com/a/29641787/321772は問題がnext()
方法は反復中tell()
を無効にすることであることを示唆しています。代わりに手作業で行ごとに読むのではなく、そのコードがCSVモジュールの中にあるので、私はそれを得ることができません。私はまた、tell()
を無効にすることでPython 3が得たことを理解できません。
だから、Python 3でファイルの行を反復処理する間にバイトオフセットを見つけるにはどうすればよいでしょうか?
あなたは 'enumerate'を使って行番号を返すことができます。このように、ファイルを2回走査しなくても、ユーザに便利なものを与えることができます。 –
@MaartenFabréもちろん、スクリプトがスタックされていないことを示すためだけに行番号を表示すると便利です。長さを知らない(すなわち、標準入力から読む)。しかし、「55%done、2 minutes remaining」を印刷するのは、「10,543,000行を読む」よりもはるかに優れています。 – Adam