2011-12-10 8 views
0

ちょうど不思議なことに、ファイルの読み取りには以下の2つの方法に違いはありますか?エッソメモリ使用量の点でファイルを読み取る2つの方法の違い

with open(...) as f: 
    for line in f: 
     <do something with line> 

f=open(...) 
    for line in f: 
     #process line 

また、私はgzipファイルについて知っています。最初のものは「with」で動作しません。 thx

+1

あなたは第二ケースをインデントしてはならない。その__exit__方法は、ファイルを閉じている間

static PyObject * file_self(PyFileObject *f) { if (f->f_fp == NULL) return err_closed(); Py_INCREF(f); return (PyObject *)f; } 

:彼は、オブジェクトの__enter__方法は、単にファイルオブジェクト自体を返しますファイル。 2番目のケースは 'f.close()'がなければ完了しません – joaquin

答えて

3

いいえ、最初のファイルが閉じていることを除いて、全く同じです。第二はしません。言い換えれば、withステートメントの本文内では、fは、2番目のコードスニペットでopenを呼び出した後に取得するfオブジェクトとまったく同じファイルオブジェクトです。

あなたが知っている(とそうでない場合は、the informative docを読んでください)かもしれませんが、with文はコンテキストマネージャインターフェイスを実装し、エントリ上のオブジェクトの__enter__メソッドを呼び出すオブジェクトを受け取り、その__exit__方法だから

{"__enter__", (PyCFunction)file_self,  METH_NOARGS, enter_doc}, 
{"__exit__", (PyCFunction)file_exit,  METH_VARARGS, exit_doc}, 

、T:それは自然かどうか、または例外を除いて(完了だ

は、ソースコード( Objects/fileobject.c)を見ると、ここではこれらの特別なメソッドのマッピング( file_methods構造の一部)です

static PyObject * 
file_exit(PyObject *f, PyObject *args) 
{ 
    PyObject *ret = PyObject_CallMethod(f, "close", NULL); 
    if (!ret) 
     /* If error occurred, pass through */ 
     return NULL; 
    Py_DECREF(ret); 
    /* We cannot return the result of close since a true 
    * value will be interpreted as "yes, swallow the 
    * exception if one was raised inside the with block". */ 
    Py_RETURN_NONE; 
} 
+0

+1可能性はあるがインタプリタへの非常に有益なダイビング –

関連する問題