2017-09-20 26 views
0

イテレータを使用してファイルから値を読み取ることは可能ですか?その結果、ファイルはイテレーションの最後に自動的に閉じられますか?ファイルから値を読み取るイテレータ

withステートメントを使用してそのようなイテレータを作成することは機能していないようです。

with open('/dev/zero', 'rb') as f:            
    values = iter(f.read(1) for i in (1, 2, 3))         

values.next()    #ValueError: I/O operation on closed file           
+0

ラッパークラスを作成し、 '__iter__'と' __next__'を実装し、 'StopIteration'を呼び出すときに' f .__ exit __() 'を呼び出す必要があります。 –

+0

あなたがやろうとしていることはお勧めできません。最後までやり直すことを忘れた場合や例外が発生した場合、ファイルハンドルをリークします。ファイルのすべての操作は 'with'の中で行うべきです! – MSeifert

答えて

2

あなたはあなたがする必要があるwith使用する場合:

def file_generator(filename): 
    with open(filename,'rb') as file: 
     for i in (1, 2, 3): 
      yield file.read(1) 

values = file_generator('/dev/zero') 
next(values) 

しかし、あなたがこのイテレータの最後に到達していない場合、あなたはファイルを閉じることはありませんので、本質的にそれはありません非常に異なっ:

file = open(filename,'rb') 
next(file) 
file.close() 

ファイルを処理することが可能な場合は、一度にすべてを通過し、その後、あなたはそれを使用して行われた後、それをクローズするのが最善ですとき。開いているファイルにハンドルを置くことは、通常、信頼できる解決策ではありません。

+1

実動コードでは実行しないでください。これは、ジェネレータが使い果たされていないときにファイルハンドルを簡単にリークしたり、例外が発生したときにジェネレータが削除されない場合があります。 (文脈の中で 'yield 'を使うと、' with'のほとんどすべての良い点が否定されます)。 – MSeifert

+0

@MSeifert私は同意します。しかし、OPはファイルにイテレータを置くことを望んでいるので、ファイルを次の2回の呼び出しの間に開いたままにしておくか、毎回閉じて再オープンしますが、満足できる解決策はありません。すべての場合、ほとんどの場合、一度にすべてのファイルを処理して閉じたり、カスタム使用のために特別なハンドルを実装したりするのが最善です。 – Flynsee

+0

@MSeifert '.close()'が呼び出されている限り、漏れはないはずですよね? –

1

fileinputモジュールがこれを行います。ファイルの開閉は自動的に処理されます。

import fileinput 

files = ['path to file'] 

iterator = fileinput.input(files) 

for line in iterator: 
    print(line) 

あなたはinputメソッドに複数のファイルパスのリストを与えることができ、それが1つのファイルを読んでいたようにそれは彼らの行を反復処理します。

+0

ありがとうございます。私は、標準の 'file'オブジェクトは既にあなたが行間を反復することを可能にすると思います。この問題は、行ではない、または連続していないビットのデータを繰り返し処理する場合に発生します。 –

関連する問題