2010-03-23 2 views
2

В pickle module documentation есть фрагмент кода примера:продолжительность питон объекта файла в списке аргументов

reader = pickle.load(open('save.p', 'rb')) 

, который при первом чтении выглядел он будет выделять системы дескриптор файла, прочитать его содержимое, а затем «утечка» открытого дескриптора, поскольку нет доступной ручки для вызова close(). Это заставило меня задуматься, есть ли скрытая магия, которая позаботится об этом случае.

Дайвинг в источник, я нашел в модулях/_fileio.c, что дескрипторы файлов закрыты файловым_деаллоком() деструктором, что привело к реальному вопросу.

Какова продолжительность файлового объекта, используемого в приведенном выше примере кода? После того, как этот оператор выполнит, действительно ли объект станет неучтенным и, следовательно, будет ли fd подвержен реальному вызову close(2) в какой-то будущей сборке мусора? Если это так, это пример хорошей практики, или не следует рассчитывать на выпуск fd, тем самым рискуя исчерпать таблицу дескриптора ядра для каждого процесса?

ответ

3

Что продолжительность объекта файла возвращаемый код примера выше?

Этот код не возврата в объекте файла (как заголовок Q в правильно говорит, он получает его в качестве аргумента).

В текущем CPython файл будет закрыт во время возвращения функции (так как функция не сбрасывает любые ссылки на файл-объект на более прочные места). В других реализациях файл будет закрыт «в конце концов», но точное время не указано.

В зависимости от семантики непосредственного закрытия CPython (которая может измениться, когда будущий CPython перемещается к лучшим механизмам сбора мусора), в то время как очень традиционный подход - не лучшая практика.

Скорее, лучшая практика заключается в использовании with заявления:

with open(...) as f: 
    reader = pickle.load(f) 

С это использования, немедленное закрытием этого файла (как только тело with заявления заканчивается) гарантируются во всех реализациях.

Обратите внимание, что в Python 2.5 вам нужен from __future__ import with_statement, чтобы использовать with. В версии 2.6 или выше такой «импорт из будущего» для этой цели не требуется (это безобидно, но если вы знаете, что никогда не будет работать до 2.5, он будет лишним и лучше удален).

+0

спасибо большое; вы были правы, я имел в виду «использовать», а не «возвращать» и редактировать, чтобы исправить. – msw

Смежные вопросы