2009-04-15 3 views
4

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

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

Это не должно быть сюрпризом, что я получаю AttributeError поскольку у есть список. Я не думал об этом, когда писал фрагмент.

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

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

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

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

+0

Я должен что-то отсутствует, но это сюрприз для меня, что вы получите AttributeError, если у есть список. –

+0

OP ссылается на строку 'y.close()', я считаю. –

+0

Вы не можете закрыть список y - это список с методом readlines(). Надеюсь, что метод - это правильное имя для строк readlines. – PyNEwbie

ответ

11

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() 

Наконец, в последнее время питона, есть 'with' заявление:

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

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

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

+0

для файла в os. listdir (dir): \t для строки в открытом виде (dir + '\\' + file, 'r'): \t \t pass Ваше предложение привело к этому. – PyNEwbie

+0

На Python 2.5 или лучше, я бы предпочел формы 'with', которые четко сообщают о намерении кода. – kquinn

+0

Yup. Обратите внимание, что вам нужно выполнить импорт __future__, чтобы получить его в python 2.5. –

3

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

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

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

Или, вы можете использовать with заявление, в котором был добавлен в Python 2.5 как from __future__ импорта, и "правильно" добавлен в 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' 
+1

Это было полезно. Мои друзья думают, что я гениальный, но потом я показываю им, как этот веб-сайт делает все возможное. – PyNEwbie

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