2016-09-30 2 views
1

Возможно ли до with open() все файлы, содержащиеся в списке, и создавать файлы для записи?Как «открыть» список файлов и получить их ручки в python?

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

fname_list = ['train_dataset.txt', 'validate_dataset.txt', 'test_dataset.txt']

, то это было бы удобно, чтобы быть в состоянии сделать:

with open('source_dataset.txt) as src_file, open(name_list, 'w') as <DONT_KNOW_WHAT_TO_DO_HERE>: 

И выполните некоторые расщепления данных внутри блока.

Редактировать: Так что мой вопрос в основном «Можно ли получить несколько файлов для списка файлов, открытых с помощью« с открытым() »?

+0

Я не уверен, как для создания нескольких файлов для списка файлов. ... open (name_list, 'w') как : – Sean

+1

Почему бы не перебрать список имен файлов, открыть и прочитать их и сохранить строковые данные для каждого из списка, который будет использоваться позже? –

+0

Поскольку набор данных может содержать миллионы строк, не будет увеличивать накладные расходы до (1 миллион) x len (list_of_filenames)? Или, может быть, это какая-то оптимизация, о которой я не должен беспокоиться? – Sean

ответ

2

В Python 3.3 и выше, contextlib.ExitStack можно использовать, чтобы правильно и красиво сделать это:

from contextlib import ExitStack 

with open('source_dataset.txt') as src_file, ExitStack() as stack: 
    files = [stack.enter_context(open(fname, 'w')) for fname in fname_list] 
    ... do stuff with src_file and the values in files ... 
... src_file and all elements in stack cleaned up on block exit ... 
+1

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

+0

@Blckknght: Yup. Я не хотел вдаваться в подробности, опасаясь маскировки простоты (ссылка на документы все равно), но да, факт, что он делает это правильно, - это не мелочь, как вы говорите. – ShadowRanger

1

Вы можете определить класс openfiles поддержать with заявление:

class openfiles: 
    def __init__(self, filelist, mode='r'): 
     self.fhandles = [open(f, mode) for f in filelist] 

    def __enter__(self): 
     return self.fhandles 

    def __exit__(self, type, value, traceback): 
     map(file.close, self.fhandles) 

Тогда вам может:

with openfiles(['file1', 'file2']) as files: 
    for f in files: 
     print(f.read()) 
+0

Вау! Это супер элегантный! –

+0

@LegoStormtroopr: Супер элегантный, но совершенно неправильный, если второй или последующий файл 'open' терпит неудачу (также, используя' map' для 'close', это плохая форма, создавая ненужные' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' даже работать над Py3). В этом случае ни один из файлов, открытых до сих пор, не детерминирован. Это потому, что так легко получить этот шаблон неправильно, что 'ExitStack' был создан. – ShadowRanger

+0

Спасибо за подробную информацию об этом. –

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