Різниця між винятком: і винятком, як e: у Python


140

Обидва наступні фрагменти коду роблять те саме. Вони ловлять кожен виняток і виконують код у except:блоці

Фрагмент 1 -

try:
    #some code that may throw an exception
except:
    #exception handling code

Фрагмент 2 -

try:
    #some code that may throw an exception
except Exception as e:
    #exception handling code

Яка саме різниця в обох конструкціях?


7
@ user2725093 це не те саме питання. Той, кого ви зв’язали, запитує, у чому різниця між except Exception, e:та except Exception as e:. Це запитання задає, в чому різниця між except:та except Exception as e:.
Денніс

Відповіді:


155

У другому ви можете отримати доступ до атрибутів об’єкта винятку:

>>> def catch():
...     try:
...         asd()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
global name 'asd' is not defined ("global name 'asd' is not defined",)

Але BaseExceptionвинятком не є або винятки SystemExit, що виходять із системи , KeyboardInterruptі GeneratorExit:

>>> def catch():
...     try:
...         raise BaseException()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in catch
BaseException

Який голий, крім:

>>> def catch():
...     try:
...         raise BaseException()
...     except:
...         pass
... 
>>> catch()
>>> 

Додаткову інформацію див. У розділі " Вбудовані винятки " в документах та в розділі " Помилки та винятки " підручника.


22
Ну, тут немає ніякої магії. Exceptionпоходить від BaseException, ось чому except Exceptionне ловить BaseException. Якщо ви напишете except BaseException, це теж буде спіймане. Голий exceptпросто все ловить.
fjarri

2
Я мушу зазначити, що голий exceptповинен бути останнім у серії exceptблоків, тоді як ви не отримаєте помилку, якщо поставите except Exceptionперед іншими exceptблоками: вони просто мовчать ігноруються (якщо вони оброблять Exceptionпідкласи). Щось слідкувати.
Ванесса Фіппс

@MatthewPhipps Це такий сенс, чи не так? як, наприклад, заяви справи або блоки if-else, виконання переходить до першої умови, яка відповідає ...
Основний

1
@Basic Тільки вказуючи на ще одну різницю між голою exceptта except Exception. "Щось на що слідкувати" зараз виглядає дещо дивно, але в той час я очікував, що Python підбере найбільш специфічний exceptблок, незалежно від того, де він був, і трохи розчарувався, дізнавшись інакше.
Ванесса Фіппс

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

51
except:

приймає всі винятки, тоді як

except Exception as e:

приймає лише винятки, які ви повинні зловити.

Ось приклад одного, якого ви не збираєтеся зловити:

>>> try:
...     input()
... except:
...     pass
... 
>>> try:
...     input()
... except Exception as e:
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

Перший замовк KeyboardInterrupt!

Ось короткий список:

issubclass(BaseException, BaseException)
#>>> True
issubclass(BaseException, Exception)
#>>> False


issubclass(KeyboardInterrupt, BaseException)
#>>> True
issubclass(KeyboardInterrupt, Exception)
#>>> False


issubclass(SystemExit, BaseException)
#>>> True
issubclass(SystemExit, Exception)
#>>> False

Якщо ви хочете зловити будь-яке з них, найкраще це зробити

except BaseException:

щоб зазначити, що ви знаєте, що робите.


Всі виключення обумовлені BaseExceptionі тим , що ви призначені , щоб зловити день у день (ті , які будуть кинуті для програміста) успадкувати теж з Exception.


except(Exception)ніколи не виявляє KeyboardInterruptпомилок. as eне має нічого спільного з цим.
пандіта

2
Я ніколи не казав, що це так. Я жодного разу не згадував про це as e, бо вважав, що це очевидно, що це робить.
Ведрак

2
Чи є випадок, коли людина піймає BaseException І знає, що вони роблять?
Давос,

2
@Davos Так, ви можете віддати перевагу під час тимчасового ведення журналу або якщо ви пропонуєте користувачеві консоль, якій ви не хочете винятків, як-от SystemExitабо KeyboardInterruptвтечі з них. Не звичайний випадок, але це трапляється.
Ведрак

14

Існують відмінності за деякими винятками, наприклад, KeyboardInterrupt.

Читання PEP8 :

Одне, окрім: пункт може спричинити винятки SystemExit і KeyboardInterrupt, що ускладнить переривання програми з Control-C і може замаскувати інші проблеми. Якщо ви хочете зафіксувати всі винятки, які посилаються на помилки програмної програми, використовуйте крім винятку: (оголене, за винятком випадків, еквівалентне, крім BaseException :)


3

Використання другої форми дає вам змінну (названу на основі asпункту у вашому прикладі e) в області exceptблоку з прив’язаним до неї об'єктом виключення, щоб ви могли використовувати інформацію у винятку (тип, повідомлення, трасування стека тощо) для обробляти виняток у більш спеціально підібраній садибі.


1

Ще один спосіб подивитися на це. Ознайомтеся з деталями винятку:

In [49]: try: 
    ...:     open('file.DNE.txt') 
    ...: except Exception as  e: 
    ...:     print(dir(e)) 
    ...:                                                                                                                                    
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'characters_written', 'errno', 'filename', 'filename2', 'strerror', 'with_traceback']

Існує багато "речей", до яких можна отримати синтаксис "як е".

Цей код призначений виключно для відображення деталей цього примірника.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.