Почему контекст слоняется после оператора with? - PullRequest
8 голосов
/ 16 февраля 2011

Я хотел бы знать, почему файловый объект, открытый с помощью оператора with или в блоке, остается в области действия после выхода.<closed file> объекты когда-либо очищены?

>>> with open('test.txt','w') as f:
...     f.write('test')
...
>>> f
<closed file 'test.txt', mode 'w' at 0x00E014F0>
>>> f.close()


>>> if True:
...     fal = open('demo.txt','w')
...     fal.write('stuff')
...     fal.close()
...
>>> fal
<closed file 'demo.txt', mode 'w' at 0x00E015A0>

Ответы [ 5 ]

16 голосов
/ 16 февраля 2011

В Python новые области (или пространства имен) только создаются для модулей, классов и функций, но не для каких-либо других операторов, особенно не для блоков with и if. Следовательно, идентификаторы, ограниченные в теле операторов with или for, связаны в самой внутренней окружающей области, которая является областью верхнего уровня интерактивного интерпретатора в вашем случае. Идентификаторы связаны в области действия до тех пор, пока эта область действительна или пока они не будут явно удалены из области (используя del, как в del fal).

Объекты могут быть очищены только тогда, когда на них больше нет ссылок. Фактический момент, в который этот объект действительно очищен, однако не определен. Python использует сборщик мусора для управления памятью и не применяет конкретную стратегию. В CPython, который использует подсчет ссылок, объекты немедленно очищаются, как только последняя ссылка выходит из области видимости. Альтернативные реализации, такие как PyPy или Jython, используют более продвинутые сборщики мусора, которые очищают объекты без ссылок в произвольные моменты времени.

Это означает, что в вашем примере объекты, связанные с f и fal, по сути, никогда не очищаются, потому что область действия интерактивного интерпретатора верхнего уровня, естественно, существует, пока работает интерпретатор. Однако помните, что это на самом деле не проблема, потому что они, тем не менее, правильно закрыты и больше не требуют никаких файловых ресурсов, а только некоторой памяти.

4 голосов
/ 16 февраля 2011

Имя останется в области действия до тех пор, пока вы не покинете область действия.

Если вы хотите очистить объект, присвойте имени другое значение, например

f = None

Это не закрывает файл!

Это хорошая привычка ограничивать области видимости, структурируя программу в функции (и, возможно, классы). Это делает его более читаемым и делает несвязанные объекты (без имен в области, которые ссылаются на объект) удобными для сборки мусора.

Обычно это не проблема, когда вы используете приглашение :)

2 голосов
/ 16 февраля 2011

with и if не создают новую область видимости, локальные переменные создаются только внутри функций, классов и модулей.См. Какова область действия переменной Python, объявленной в операторе if?

0 голосов
/ 16 февраля 2011

Оператор Python with вызывает метод __exit__ класса файла [который в случае файлов закрывает их].Не удаляет объект;он очищается только тогда, когда вы явно очищаете его или закрываете программу / интерпретатор.

0 голосов
/ 16 февраля 2011

Файловый объект, как и любой другой объект, «зависает» на время вашей программы, пока он не будет удален (вызывается метод __del__).

del f вызовет сборку мусора f сборщиком мусора Python. Это происходит автоматически, когда вы выходите из области действия, ваш сценарий завершается или в вашем примере сеанс интерпретатора заканчивается.

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