Должен ли класс или метод, обрабатывающий файл, закрыть файл как побочный эффект? - PullRequest
2 голосов
/ 27 января 2010

Мне интересно, какой из методов Pythonic лучше использовать для обработки файлов? Должен ли метод, обрабатывающий файл, закрыть этот файл в качестве побочного эффекта? Должна ли концепция данных как «файл» быть полностью абстрагирована от метода, который обрабатывает данные, а это значит, что он должен ожидать некоторый «поток», но не обязательно файл?

Например, нормально ли это делать:

process(open('somefile','r'))
... carry on

Где process() закрывает дескриптор файла:

def process(somefile):
    # do some stuff with somefile
    somefile.close()

Или это лучше:

file = open('somefile','r')
process(file)
file.close()

Что бы это ни стоило, я обычно использую Python для написания относительно простых сценариев, которые имеют исключительно конкретную цель, и я, вероятно, буду единственным, кто их использует. Тем не менее, я не хочу учить себя никаким плохим практикам, и я бы лучше изучил лучший способ сделать что-то, поскольку даже небольшая работа стоит делать хорошо.

Ответы [ 3 ]

4 голосов
/ 27 января 2010

Использование with означает, что вам не нужно об этом беспокоиться.

Как минимум, не на 2,5+.

4 голосов
/ 27 января 2010

Как правило, для открывателя файла лучше закрыть файл.В вашем вопросе второй пример лучше.

Это предотвращает возможные путаницы и недопустимые операции.

Правка: Если ваш реальный код не соответствуетболее сложный, чем ваш пример кода, тогда может быть лучше просто открыть и закрыть файл process (), так как вызывающая сторона не использует этот файл ни для чего другого.Просто введите путь / имя файла.Но если возможно, что вызывающий для process () будет использовать файл до его закрытия, тогда оставьте файл открытым и закройте операции за пределами process ().

0 голосов
/ 27 января 2010

Нет, потому что это уменьшает гибкость: если функция не закрывает файл, а вызывающая сторона не нуждается в нем - вызывающая сторона может закрыть файл. Если это так, но вызывающему по-прежнему требуется открыть файл - вызывающий застрял с повторным открытием файла, используя StringIO или что-то еще.

Кроме того, закрытие файлового объекта требует дополнительных предположений о его реальном типе (объект может поддерживать .read () или .write (), но не имеет значимого .close ()), что препятствует типизированию утки.

И файлы-оставленные-открытые не являются проблемой для CPython - они будут закрыты на сборке мусора сразу после чего-либо (open ('somefile')). (другая реализация также выполнит gc и закроет файл, но в неуказанный момент)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...