Czy to właściwy sposób używania instrukcji Pythona „with” w połączeniu z blokiem try-except ?:
try:
with open("file", "r") as f:
line = f.readline()
except IOError:
<whatever>
Jeśli tak, to rozważ stary sposób robienia rzeczy:
try:
f = open("file", "r")
line = f.readline()
except IOError:
<whatever>
finally:
f.close()
Czy główną zaletą instrukcji „with” jest to, że możemy pozbyć się trzech wierszy kodu? Nie wydaje mi się to zbyt ważne w tym przypadku użycia (chociaż rozumiem, że instrukcja „with” ma inne zastosowania).
EDYCJA: Czy funkcjonalność powyższych dwóch bloków kodu jest identyczna?
EDYCJA2: Kilka pierwszych odpowiedzi mówi ogólnie o korzyściach wynikających z używania „z”, ale wydaje się, że mają one marginalne korzyści. Od lat wszyscy (lub powinniśmy) otwarcie wywoływać funkcję f.close (). Przypuszczam, że jedną z korzyści jest to, że niechlujni programiści skorzystają na używaniu „z”.
Odpowiedzi:
finally
klauzuli, ponieważf
nie jest powiązany.Odpowiedni kod w starym stylu wyglądałby tak:
try: f = open("file", "r") try: line = f.readline() finally: f.close() except IOError: <whatever>
Jak widać,
with
stwierdzenie to może zmniejszyć podatność na błędy. W nowszych wersjach Pythona (2.7, 3.1) można również łączyć wiele wyrażeń w jednejwith
instrukcji. Na przykład:with open("input", "r") as inp, open("output", "w") as out: out.write(inp.read())
Poza tym osobiście uważam, że jak najwcześniejsze wyłapywanie wyjątków jest złym nawykiem. To nie jest celem wyjątków. Jeśli funkcja IO, która może zawieść, jest częścią bardziej skomplikowanej operacji, w większości przypadków IOError powinien przerwać całą operację i dlatego powinien być obsługiwany na zewnętrznym poziomie. Używając
with
instrukcji, możesz pozbyć się wszystkich tychtry...finally
instrukcji na wewnętrznych poziomach.źródło
Jeśli zawartość
finally
bloku jest określona przez właściwości otwieranego obiektu pliku, dlaczego implementujący obiekt pliku nie miałby zapisywaćfinally
bloku? To zaletawith
instrukcji, znacznie większa niż zapisanie trzech wierszy kodu w tym konkretnym przypadku.I tak, sposób, w jaki połączyłeś
with
itry-except
jest właściwie jedynym sposobem na zrobienie tego, ponieważ wyjątkowych błędów spowodowanych w samymopen
oświadczeniu nie można złapać wwith
bloku.źródło
Myślę, że źle zrozumiałeś stwierdzenie „z”, że zmniejsza ono tylko linie. W rzeczywistości wykonuje inicjalizację i obsługuje porzucanie.
W twoim przypadku „z” robi
Oto link do zrozumienia instrukcji „with”: http://effbot.org/zone/python-with-statement.htm
Edycja: Tak, twoje użycie "z" jest poprawne, a funkcjonalność obu bloków kodu jest identyczna. Pytanie o to, dlaczego używać słowa „z”? dzieje się tak ze względu na korzyści, jakie z nim uzyskasz. jak wspomniałeś o przypadkowym braku f.close ().
źródło
Bardziej Pythonowy sposób na następujące kody to:
try: f = open("file", "r") try: line = f.readline() finally: f.close() except IOError: <whatever> try: f = open("file", "r") except IOError: <whatever> else: f.close()
źródło
readline()
wywołanie, Twoja wersja nie zamknie pliku, jeślireadline()
w wynikuIOError
.