2009-05-21 11 views
218

Czy można zadeklarować więcej niż jedną zmienną za pomocą instrukcji with w Pythonie?Wiele zmiennych w Pythonie z instrukcją

Coś jak:

from __future__ import with_statement 

with open("out.txt","wt"), open("in.txt") as file_out, file_in: 
    for line in file_in: 
     file_out.write(line) 

... lub jest sprzątanie dwa zasobów jednocześnie problem?

+0

Może tak: z [wyraż1, wyr2] Jak f: a następnie za pomocą F [0] F [1]. – jbasko

+0

Byłoby miło, ponieważ nie trzeba importować czegoś .... ale to nie działa AttributeError: obiekt 'list' nie ma atrybutu '__exit__' – pufferfish

+0

Jeśli pyton miał tylko zamknięcia, nie potrzebowałbyś instrukcji with –

Odpowiedz

411

Jest to możliwe w Python 3 since v3.1 i Python 2.7. Nowy with syntax obsługuje wiele menedżerów kontekstu:

with A() as a, B() as b, C() as c: 
    doSomething(a,b,c) 

przeciwieństwie do contextlib.nested, to gwarantuje, że a i b będzie miał ich __exit__() się nazywa nawet jeśli C() czy to __enter__() metoda zgłasza wyjątek.

+0

jest to możliwe ustawić pola równe coś z instrukcją jak w 'with open (" ./ plik ") jako arg.x = file:'? –

+3

Jest również możliwe: z A() jako a, B (a) jako b, C (a, b) jako c: –

+0

test klasy2: x = 1; t2 = test2() z otwartym ("f2.txt") jako t2.x: dla l1 w t2.x.readlines(): druk (l1); # Charlie Parker # testowany w pythonie 3.6 –

18

Chyba, że ​​chcesz to zrobić w zamian:

from __future__ import with_statement 

with open("out.txt","wt") as file_out: 
    with open("in.txt") as file_in: 
     for line in file_in: 
      file_out.write(line) 
+2

Tak właśnie to teraz robię, ale wtedy zagnieżdżanie jest dwa razy głębsze, jak chcę (w zasadzie) to jest ... – pufferfish

+0

Myślę, że jest to najczystsze podejście - każde inne podejście będzie trudniejsze do odczytania. Odpowiedź Alexa Martellego wydaje się bliższa temu, co się chce, ale jest znacznie mniej czytelna. Dlaczego takie zagnieżdżanie się powoduje problemy? –

+5

Nie jest to wielka sprawa, ale, per "import this" (inaczej "Zen of Python"), "mieszkanie jest lepsze niż zagnieżdżone" - dlatego dodaliśmy contextlib.nested do standardowej biblioteki. BTW, 3.1 może mieć nową składnię "z A() jako a, B() jak b:" (łatka jest obecna, nie ma już mowy o BDFL), aby uzyskać bardziej bezpośrednie wsparcie (tak wyraźnie, że rozwiązanie biblioteki nie jest " t za idealne ...ale unikanie niechcianego zagnieżdżania jest zdecydowanie szeroko rozpowszechnionym celem wśród głównych twórców Pythona). –

53

contextlib.nested obsługuje to:

import contextlib 

with contextlib.nested(open("out.txt","wt"), open("in.txt")) as (file_out, file_in): 

    ... 

Aktualizacja:
Cytując dokumentację, dotyczącą contextlib.nested:

Deprecated since version 2.7: The with-statement now supports this functionality directly (without the confusing error prone quirks).

Aby uzyskać więcej informacji, zobacz Rafał Dowgird's answer.

+27

Przykro mi to mówić, ale myślę, że menedżer kontekstowy 'zagnieżdżony' jest pomyłką i nigdy nie powinien być używany. W tym przykładzie, jeśli otwarcie drugiego pliku spowoduje zgłoszenie wyjątku, pierwszy plik nie zostanie w ogóle zamknięty, co całkowicie zniszczy cel korzystania z menedżerów kontekstów. –

+0

Dlaczego tak mówisz? Dokumentacja mówi, że użycie zagnieżdżonego jest równoznaczne z zagnieżdżeniem 'with's –

+0

@Rafal: rzut oka na podręcznik zdaje się wskazywać, że pyton prawidłowo gniazduje instrukcjami on. Prawdziwy problem polega na tym, że drugi plik zgłasza wyjątek podczas zamykania. – Unknown

Powiązane problemy