2011-12-10 26 views
0

只是好奇,下面兩種方式對文件閱讀有什麼區別嗎? ESO。在內存使用方面。閱讀文件的兩種方式的差異

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

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

另外我知道gzip文件,第一個'with'不能工作。 THX

+1

你不能縮進的第二種情況。第二種情況是不完整的,沒有'f.close()'行 – joaquin

回答

3

不,他們很相同,不同之處在於第一個確保文件被關閉。第二個不是。換句話說,在with聲明體內,f只是一個文件對象,它是完全等同於f對象,你只是在第二代碼片段調用open後得到的。

正如你可能知道(如果你不這樣做,請務必閱讀the informative doc),該with語句接受一個實現了上下文管理器界面,並調用條目的對象的__enter__方法的對象,其__exit__方法時。它的工作(無論是自然,或與異常

查看源代碼(Objects/fileobject.c),這裏是爲這些特殊的方法映射(該file_methods結構的一部分):

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

因此,T他File對象__enter__方法只返回文件對象本身:

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

雖然其__exit__方法關閉文件:

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爲可能不必要的,但非常翔實的潛水翻譯:) –