2011-01-06 7 views
420

Chcę zmienić kilka plików jednocześnie, iff Mogę napisać do wszystkich z nich. Zastanawiam się, czy w jakiś sposób można połączyć wiele połączeń otwartych ze stwierdzeniem with:Jak mogę otworzyć wiele plików za pomocą "with open" w Pythonie?

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 

Jeśli nie jest to możliwe, co byłoby eleganckie rozwiązanie tego problemu wyglądać?

Odpowiedz

652

Jak Pythona 2.7 (lub 3.1 odpowiednio) można napisać

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

We wcześniejszych wersjach Pythona, można czasem użyć contextlib.nested() do menedżerów kontekstowych gniazdowych. Nie będzie to jednak działać zgodnie z oczekiwaniami w przypadku otwierania plików wielokrotnych - szczegółowe informacje można znaleźć w powiązanej dokumentacji.

+0

Tak .. tak chłodne, że kilka linii kodu, które pozwalają robić w poprzednich wersjach Pythona, jak również, jak w tym przykładzie tutaj: http://metapython.blogspot.com/2010/12/multiple-contests-in-with-statement-not.html – jsbueno

+3

Niestety, zgodnie z dokumentacją contextlib.nested, nie powinieneś go używać dla otwierania plików: "używanie nested() do otwierania dwóch plików jest błędem programistycznym, ponieważ pierwszy plik nie zostanie szybko zamknięty, jeśli zostanie zgłoszony wyjątek podczas otwierania drugiego pliku." – weronika

+17

Czy istnieje sposób użycia 'with' do otwarcia listy zmiennych plików? – monkut

77

Wystarczy zastąpić and z , i gotowe:

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

Powinieneś określić, które wersje Pythona obsługują tę składnię. –

31

do otwierania wielu plików naraz lub na długie ścieżki do plików, może być przydatna do zerwania rzeczy na wielu liniach. Z Python Style Guide jako sugerowane przez @Sven Marnach w komentarzach do innej odpowiedzi:

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

Zagnieżdżony ze sprawozdania zrobi to samo zadanie, i moim zdaniem, są łatwiejsze do czynienia.

Załóżmy, że masz plik inFile.txt i chcesz zapisać go jednocześnie w dwóch plikach 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:

Nie rozumiem przyczynę downvote. Przetestowałem swój kod przed opublikowaniem odpowiedzi i działa on tak, jak powinien: zapisuje się do wszystkich plików outFile, tak jak pyta. Bez duplikowania zapisu lub bez zapisu. Tak więc jestem ciekawa, dlaczego moja odpowiedź jest błędna, suboptymalna lub coś podobnego.

+1

Nie wiem, komu ktoś cię zawiódł, ale UPWRÓCIŁam Cię, ponieważ jest to jedyny przykład, który miał trzy pliki (jedno wejście, dwa wyjścia), który akurat był tym, czego potrzebowałem. –

+0

Dzięki @AdamWood! Bardzo się cieszę, że mogę pomóc. Wesołych świąt! – FatihAkici

0

z Python 2.6 nie będzie działać, musimy skorzystać z poniższego sposobu otwierania wielu plików:

with open('a', 'w') as a: 
    with open('b', 'w') as b: 
Powiązane problemy