Как узнать, когда управлять ресурсами в Python - PullRequest
4 голосов
/ 16 апреля 2009

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

for file in os.listdir(dir):
    y=open(dir+'\\'+file,'r').readlines()
    for line in y:
        pass
    y.close()

Не удивительно, что я получаю AttributeError, поскольку y - это список. Я не думал об этом, когда писал фрагмент.

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

Я могу исправить код, чтобы он работал, и я явно закрываю файлы после их открытия. Мне любопытно, если мне нужно, или если Python обрабатывает закрытие файла в следующей итерации цикла. Если так, то мне нужно только написать:

for file in os.listdir(dir):
    y=open(dir+'\\'+file,'r').readlines()
    for line in y:
        pass

Я предполагаю, что он (python) справляется с этим без особых усилий. Причина, по которой я думаю, что это может быть обработано, в том, что я изменил объект / вещь, на которую ссылается y. Когда я запускаю вторую итерацию, в памяти больше нет ссылок на файл, который был открыт и прочитан методом readlines.

Ответы [ 2 ]

11 голосов
/ 16 апреля 2009

Python закроет открытые файлы, когда они будут собирать мусор, поэтому обычно вы можете об этом забыть - особенно при чтении.

Тем не менее, если вы хотите закрыть явно, вы можете сделать это:

for file in os.listdir(dir):
    f = open(dir+'\\'+file,'r')
    y = f.readlines()
    for line in y:
        pass
    f.close()

Однако мы можем немедленно улучшить это, потому что в python вы можете перебирать объекты, похожие на файлы:

for file in os.listdir(dir):
    y = open(dir+'\\'+file,'r')
    for line in y:
        pass
    y.close()

Наконец, в недавнем Python есть оператор ' с ':

for file in os.listdir(dir):
    with open(dir+'\\'+file,'r') as y:
        for line in y:
            pass

Когда блок with закончится, python закроет файл для вас и очистит его.

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

3 голосов
/ 16 апреля 2009

Не беспокойся об этом. Сборщик мусора в Python хорош, и у меня никогда не было проблем с закрытием файловых указателей (по крайней мере, для операций чтения)

Если вы хотите явно закрыть файл, просто сохраните open() в одной переменной, а затем вызовите readlines() для этого, например ..

f = open("thefile.txt")
all_lines = f.readlines()
f.close()

Или вы можете использовать оператор with, который был добавлен в Python 2.5 как from __future__ import и "правильно" добавлен в Python 2.6:

from __future__ import with_statement # for python 2.5, not required for >2.6

with open("thefile.txt") as f:
    print f.readlines()

# or

the_file = open("thefile.txt")
with the_file as f:
    print f.readlines()

Файл будет автоматически закрыт в конце блока.

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

Во-первых, старайтесь избегать ручного построения путей с использованием конкатенации строк. Модуль os.path содержит множество способов сделать это более надежным, кроссплатформенным способом.

import os
y = open(os.path.join(dir, file), 'r')

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

[W0622] Redefining built-in 'file'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...