Использование инструкции python с инструкцией с блоком try-except
Правильно ли это использовать оператор python с инструкцией в сочетании с блоком try-except?:
try:
with open("file", "r") as f:
line = f.readline()
except IOError:
<whatever>
Если это так, то, учитывая старый способ делать вещи:
try:
f = open("file", "r")
line = f.readline()
except IOError:
<whatever>
finally:
f.close()
Является основным преимуществом выражения "with" здесь, что мы можем избавиться от трех строк кода? Мне кажется, что это не убедительно для меня для этого случая использования (хотя я понимаю, что оператор "с" имеет другие применения).
EDIT: Является ли функциональность этих двух блоков кода одинаковой?
EDIT2: первые несколько ответов говорят в основном о преимуществах использования "с" , но они кажутся здесь предельной выгодой. Мы все были (или должны были) явно называть f.close() годами. Я полагаю, что одно преимущество заключается в том, что неаккуратные кодеры получат выгоду от использования "с" .
Ответы
Ответ 1
- Два кода, которые вы указали,
не эквивалент
- Код, который вы описали как старый способ
от того, что происходит, имеет серьезную ошибку:
в случае открытия файла вам не удастся
получит второе исключение в
finally
, потому что f
не
оценка.
Эквивалентным старым кодом стиля будет:
try:
f = open("file", "r")
try:
line = f.readline()
finally:
f.close()
except IOError:
<whatever>
Как вы можете видеть, оператор with
может сделать вещи менее подверженными ошибкам. В новых версиях Python (2.7, 3.1) вы также можете комбинировать несколько выражений в одном выражении with
. Например:
with open("input", "r") as inp, open("output", "w") as out:
out.write(inp.read())
Кроме того, я лично считаю это вредной привычкой улавливать любое исключение как можно раньше. Это не является целью исключения. Если функция ввода-вывода, которая может выйти из строя, является частью более сложной операции, в большинстве случаев IOError должен прервать всю операцию и поэтому обрабатываться на внешнем уровне. Используя инструкции with
, вы можете избавиться от всех этих операторов try...finally
на внутренних уровнях.
Ответ 2
Если содержимое блока finally
определяется свойствами открытого файлового объекта, почему разработчику файлового объекта не следует писать блок finally
? Это преимущество оператора with
, намного больше, чем сохранение трех строк кода в данном конкретном случае.
И да, то, как вы объединили with
и try-except
, - это единственный способ сделать это, поскольку исключительные ошибки, вызванные в самом выражении open
, не могут быть обнаружены в пределах with
блок.
Ответ 3
Я думаю, что вы ошиблись в утверждении о том, что это только уменьшает количество строк.
Он фактически выполняет инициализацию и ручную срыв.
В вашем случае "с" делает
- откройте файл,
- обрабатывает его содержимое и
- обязательно закройте его.
Вот ссылка для понимания инструкции "with": http://effbot.org/zone/python-with-statement.htm
Изменить: Да, правильное использование "с" и функциональность обоих блоков кода одинаковы.
Вопрос о том, почему использовать "с" ? это из-за преимуществ, которые вы получаете с этим. как вы упомянули о случайно отсутствующем f.close().
Ответ 4
Чем больше Pythonic способ для следующих кодов:
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()