好奇,下面两种文件阅读方式有什么不同吗? ESO。在内存使用方面。
with open(...) as f:
for line in f:
<do something with line>
f=open(...)
for line in f:
#process line
我也知道gzip文件,第一个带'with'的文件无效。 THX
答案 0 :(得分: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},
因此,文件对象的__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;
}