Нет, они совершенно идентичны, за исключением того, что первый гарантирует, что файл закрыт.Второго нет.Другими словами, в теле оператора with
, f
- это просто файловый объект, который в точности эквивалентен объекту f
, который вы получаете после простого вызова open
во втором фрагменте кода.
Как вы, возможно, знаете (а если нет, обязательно прочитайте информативный документ ), оператор 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;
}