/ / Призначення іншого та, нарешті, виключення поводження [дублікат] - python

Мета іншого і, нарешті, обробки виключення [дублікат] - python

Є else і finally розділи виключень, що обробляють надлишки? Наприклад, чи є різниця між наступними двома фрагментами коду?

try:
foo = open("foo.txt")
except IOError:
print("error")
else:
print(foo.read())
finally:
print("finished")

і

try:
foo = open("foo.txt")
print(foo.read())
except IOError:
print("error")
print("finished")

Більш загально, не можна вмісту else завжди переміщуватися в try, і не можна вміст finally просто перенести за межі блоку спробувати / ловити? Якщо так, то яка мета else і finally? Це просто для підвищення читабельності?

Відповіді:

50 для відповіді № 1

Ідея полягає в тому, щоб ви зберігали код, для якого ви обробляєте винятки, якомога менше. Що-небудь в else блок міг переїхати в try, так, але тоді ви, можливо, захочете виняток, коли дійсно хочете, щоб його підняли. Можливо, ви успішно відкрили файл, але якщо read викликає IOError і це "в try, що теж буде спіймано.

Від кінський рот:

Використання else пункт краще, ніж додавання додаткового коду до try застереження, оскільки це дозволяє уникнути випадкового потрапляння на виняток, який не був порушений кодом, захищеним try ... except заява

Як вже було сказано в двох інших відповідях finally блок є для коду, який буде виконуватися незалежно від того, піднято виняток де завгодно, у тому числі всередині else або exceptта чи обробляється цей виняток чи ні. Канонічний випадок використання для цього забезпечує абсолютно впевненість, що ручка файлу закрита, незалежно від того. *

The офіційне фразування це:

Коли виняток стався в try пункт, і його не обробляли except пункт (або це сталося в a except або else пункт), воно повторно піднімається після finally пункт виконується. The finally Стаття також виконується "на виході", коли будь-яке інше положення try Заява залишається через break, continue, або return заява


* Це конкретно використання було дещо заперечене менеджерами контексту (with...as блоки).


34 за відповідь № 2

finally виконується незалежно від того, чи не вдаються або успішні висловлювання у блоці спробу. else виконується лише в тому випадку, якщо висловлювання у блоці спробу не створюють винятку.


10 за відповідь № 3

Незалежно від того, що станеться, блок в finally завжди отримує страту. Навіть якщо виняток не оброблявся або обробники винятків генерували нові винятки.


7 для відповіді № 4

Якщо ви перемістите вміст else блок всередині try блоку, ви також будете ловити винятки, які можуть статися під час else блок. Якщо рядок

print(foo.read())

у вашому прикладі викидає IOError, ваш перший фрагмент коду не здобуде помилку, тоді як ваш другий фрагмент буде try як можна менше блоків, щоб насправді виловлювати лише ті винятки, які ви хочете спіймати.

The finally блок завжди виконується, незалежно від того. Якщо, наприклад, try блок містить a return заява, а finally блок все одно буде виконуватися, тоді як будь-який код під цілим try/except блок виграв "т.