2011-07-01 10 views
2

次のコードは、すべてをメモリにロードするのではなく、行ごとにロードすることがわかります。すなわち、OSイテレータはすべてキャッシュされていますか? csv.Readerはどうですか?

def fileGen(file): 
    for line in file: 
     yield line 

with open("somefile") as file: 
    for line in fileGen(file): 
     print line 

が、ために何とか「削除可能」とマークされます読んラインalreadは、我々は次のようにのfilegenの定義を変更した場合、これはまだ本当であるかどうかを確認できとにかくありますか?

def fileGen(file): 
    for line in csv.Reader(file): 
     yield line 

csv.Readerがロードしたデータをキャッシュするかどうかわかりましたか?おかげ

に関して、csv.readerが何をしているかを調べるため ジョン

答えて

4

最も信頼性の高い方法は、ソースを読むことです。 _csv.cの773行目以降を参照してください。読者オブジェクトには、基礎となるイテレータ(通常はファイルイテレータ)へのポインタがあり、別の行が必要になるたびにPyIter_Nextが呼び出されます。したがって、ロードされたデータを先読みしたりキャッシュしたりすることはありません。

csv.readerが行っていることを調べるもう1つの方法は、照会されているときに報告できるモックファイルオブジェクトを作成することです。たとえば:

class MockFile: 
    def __init__(self): self.line = 0 
    def __iter__(self): return self 
    def next(self): 
     self.line += 1 
     print "MockFile line", self.line 
     return "line,{0}".format(self.line) 

>>> r = csv.reader(MockFile()) 
>>> next(r) 
MockFile line 1 
['line', '1'] 
>>> next(r) 
MockFile line 2 
['line', '2'] 

これは、我々はcsvソースコードを読んでから学んだことを確認し:それは唯一、独自のnextメソッドが呼び出された基本的なイテレータから次の行を要求します。


ジョンは、彼の関心はcsv.readerはPythonのメモリマネージャによって収集されてからそれらを防ぐこと、生きている行を続けるかどうかであること(コメントを参照してください)、それが明らかにしました。

また、コードを読み(最も信頼性が高い)、または実験を試みることができます。 Reader_iternextの実装を_csv.cに見ると、lineobjはその根底にあるイテレータによって返されたオブジェクトに与えられた名前であり、コードを通るすべてのパスにPy_DECREF(lineobj)という呼び出しがあります。だからcsv.readerlineobjを生き残らない。

これを確認するための実験は次のとおりです。

class FinalizableString(string): 
    """A string that reports its deletion.""" 
    def __init__(self, s): self.s = s 
    def __str__(self): return self.s 
    def __del__(self): print "*** Deleting", self.s 

class MockFile: 
    def __init__(self): self.line = 0 
    def __iter__(self): return self 
    def next(self): 
     self.line += 1 
     return FinalizableString("line,{0}".format(self.line)) 

>>> r = csv.reader(MockFile()) 
>>> next(r) 
*** Deleting line,1 
['line', '1'] 
>>> next(r) 
*** Deleting line,2 
['line', '2'] 

それでは、彼らがタイムリーにガベージコレクションを取得、あなたはcsv.readerは、そのイテレータから取得するオブジェクトにハングアップしないことを確認することができ、そして他には何も生きている彼らを維持されていない場合。


私には、あなたが私たちに言っていない以上のことがあると感じています。あなたはなぜこれについて心配しているのか説明できますか?

+0

emmm、上記のコードで "先読みしません"のところが正しいですが、それがrequirs ['line'、2]の後で[hold] ['Line'、1]これが私の主な関心事です。 – John

+0

更新された回答(およびあなたの質問)を参照してください。 –

+0

こんにちはガレス、更新のおかげで、私は今、もっと自信を持っていると思います。私はいくつかの巨大なサイズのファイルを処理するスクリプトを書くようにしようとしているので、コードがすべてのメモリを消費しないようにしたいと思います...私はファイルにデータを書き込む前にいくつかのバッファリングを行いますが、csvリーダーが何らかの形でデータをキャッシュしないようにしたい場合は、バッファがオンザフライでバッファに意味がなくなります – John

関連する問題