只是好奇,下面兩種方式對文件閱讀有什麼區別嗎? ESO。在內存使用方面。閱讀文件的兩種方式的差異
with open(...) as f:
for line in f:
<do something with line>
f=open(...)
for line in f:
#process line
另外我知道gzip文件,第一個'with'不能工作。 THX
只是好奇,下面兩種方式對文件閱讀有什麼區別嗎? ESO。在內存使用方面。閱讀文件的兩種方式的差異
with open(...) as f:
for line in f:
<do something with line>
f=open(...)
for line in f:
#process line
另外我知道gzip文件,第一個'with'不能工作。 THX
不,他們很相同,不同之處在於第一個確保文件被關閉。第二個不是。換句話說,在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;
}
+ 1爲可能不必要的,但非常翔實的潛水翻譯:) –
你不能縮進的第二種情況。第二種情況是不完整的,沒有'f.close()'行 – joaquin