Отличия двух способов чтения файла - PullRequest
0 голосов
/ 10 декабря 2011

Просто любопытно, есть ли разница между двумя способами ниже для чтения файлов? Eso. с точки зрения использования памяти.

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

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

Также я знаю, что для файла gzip первый файл с 'with' не может работать. ТНХ

1 Ответ

3 голосов
/ 10 декабря 2011

Нет, они совершенно идентичны, за исключением того, что первый гарантирует, что файл закрыт.Второго нет.Другими словами, в теле оператора 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;
}
...