Czy można zadeklarować więcej niż jedną zmienną przy użyciu with
instrukcji w Pythonie?
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)
... czy problem polega na oczyszczeniu dwóch zasobów jednocześnie?
python
with-statement
rozdymka tygrysia
źródło
źródło
Odpowiedzi:
Jest to możliwe w Pythonie 3 od wersji 3.1 i Pythona 2.7 . Nowa
with
składnia obsługuje wiele menedżerów kontekstu:W odróżnieniu od
contextlib.nested
gwarantuje to, żea
ib
będzie miał swój__exit__()
„nazywa nawet jeśliC()
czy jest to__enter__()
metoda zgłasza wyjątek.Możesz także użyć wcześniejszych zmiennych w późniejszych definicjach (h / t Ahmad poniżej):
źródło
with open('./file') as arg.x = file:
?as
jest opcjonalny.as
jest wymagane, jeśli potrzebujesz przedmiotua
lubb
, ale całośćas a
lubas b
nie jest wymaganecontextlib.nested
popiera to:Aktualizacja:
Aby zacytować dokumentację dotyczącą
contextlib.nested
:Więcej informacji można znaleźć w odpowiedzi Rafała Dowgirda .
źródło
nested
menedżer kontekstu jest błędem i nigdy nie powinien być używany. W tym przykładzie, jeśli otwarcie drugiego pliku spowoduje wyjątek, pierwszy plik w ogóle nie zostanie zamknięty, co całkowicie zniszczy cel używania menedżerów kontekstu.with
bloków. Menedżery są tworzone w kolejności przed wejściem do bloków: m1, m2, m3 = A (), B (), C () Jeśli B () lub C () zawiedzie z wyjątkiem, to jedyną nadzieją na prawidłowe sfinalizowanie A ( ) jest śmieciarzem.Zauważ, że jeśli podzielisz zmienne na linie, musisz użyć ukośników odwrotnych do zawijania nowych linii.
Nawiasy nie działają, ponieważ zamiast tego Python tworzy krotkę.
Ponieważ w krotkach brakuje
__enter__
atrybutu, pojawia się błąd (nieopisowy i nie identyfikuje typu klasy):Jeśli spróbujesz użyć
as
w nawiasach, Python łapie błąd podczas analizy:Wydaje się, że https://bugs.python.org/issue12782 ma związek z tym problemem.
źródło
Myślę, że zamiast tego chcesz to zrobić:
źródło
Od wersji Python 3.3 możesz używać klasy
ExitStack
zcontextlib
modułu.Może zarządzać dynamiczną liczbą obiektów kontekstowych, co oznacza, że okaże się szczególnie przydatny, jeśli nie wiesz, ile plików zamierzasz obsłużyć.
Kanoniczny przypadek użycia wymieniony w dokumentacji zarządza dynamiczną liczbą plików.
Oto ogólny przykład:
Wynik:
źródło
W Pythonie 3.1+ można określić wiele wyrażeń kontekstowych, które będą przetwarzane tak, jakby
with
zagnieżdżono wiele instrukcji:jest równa
Oznacza to również, że możesz użyć aliasu z pierwszego wyrażenia w drugim (przydatne podczas pracy z połączeniami / kursorami db):
źródło