2011-01-06 2 views
420

Я хочу изменить пару файлов за один раз, iff Я могу написать для всех из них. Я интересно, если я каким-то образом можно объединить несколько открытых вызовов с with высказыванием:Как открыть несколько файлов с помощью «с открытым» в Python?

try: 
    with open('a', 'w') as a and open('b', 'w') as b: 
    do_something() 
except IOError as e: 
    print 'Operation failed: %s' % e.strerror 

Если это не представляется возможным, что бы элегантное решение этой проблемы выглядеть?

ответ

652

По состоянию на Python 2.7 (или 3.1 соответственно) вы можете написать

with open('a', 'w') as a, open('b', 'w') as b: 
    do_something() 

В более ранних версиях Python, вы можете иногда использовать contextlib.nested() для гнездовых менеджеров контекста. Это не будет работать, как ожидалось, для открытия многократных файлов, однако - подробности см. В связанной документации.

+0

Да .. так здорово, что несколько строк кода позволяют делать это в предыдущих версиях питона, а также, как в этом примере здесь: http://metapython.blogspot.com/2010/12/multiple-contests-in-with-statement-not.html – jsbueno

+3

К сожалению, согласно документам contextlib.nested, вы не должны использовать его для открытия файла: «использование вложенных() для открытия двух файлов - это ошибка программирования, так как первый файл не будет закрыт оперативно, если при открытии второго файла возникает исключение». – weronika

+17

есть ли способ использовать 'with' для открытия списка переменных? – monkut

77

Просто замените and с , и вы сделали:

try: 
    with open('a', 'w') as a, open('b', 'w') as b: 
     do_something() 
except IOError as e: 
    print 'Operation failed: %s' % e.strerror 
+0

Вы должны указать, какие версии Python поддерживают этот синтаксис. –

31

Для открытия много файлов сразу или для длинных путей к файлам, это может быть полезно, чтобы разбить вещи на несколько строк. Из Python Style Guide как это было предложено @Sven Marnach в комментариях к другой ответ:

with open('/path/to/InFile.ext', 'r') as file_1, \ 
    open('/path/to/OutFile.ext', 'w') as file_2: 
    file_2.write(file_1.read()) 
2

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

Предположим, у вас есть inFile.txt, и вы хотите записать его в два outFile одновременно.

with open("inFile.txt", 'r') as fr: 
    with open("outFile1.txt", 'w') as fw1: 
     with open("outFile2.txt", 'w') as fw2: 
      for line in fr.readlines(): 
       fw1.writelines(line) 
       fw2.writelines(line) 

EDIT:

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

+1

Я не знаю, что кто-то еще вас ниспровергал, но я ОБНОВЛЯЛ вас, потому что это единственный пример, в котором было три файла (один вход, два вывода), который оказался именно тем, что мне нужно. –

+0

Спасибо @AdamWood! Очень рад слышать, что могу помочь. Счастливых праздников! – FatihAkici

0

С Python 2.6 не будет работать, мы должны использовать ниже способ открыть несколько файлов:

with open('a', 'w') as a: 
    with open('b', 'w') as b: 
Смежные вопросы