Почему "if Exception" работает в Python
В этом ответе https://stackoverflow.com/a/27680814/3456281 представлена следующая конструкция
a=[1,2]
while True:
if IndexError:
print ("Stopped.")
break
print(a[2])
который на самом деле печатает "Stopped". и разрывы (проверены с помощью Python 3.4.1).
Почему?! Почему if IndexError
даже законный? Почему a[2]
не поднимает IndexError
без try ... except
вокруг?
Ответы
Ответ 1
Все объекты имеют логическое значение. Если не определено иначе, это логическое значение имеет значение True.
Итак, этот код просто эквивалентен выполнению if True
; поэтому выполнение достигает инструкции break
сразу, а print
никогда не достигается.
Ответ 2
Просмотр документации Python , раздел Тестирование значения истины в разделе "Встроенные типы стандартной библиотеки Python". Первое предложение, а первое предложение после последнего пункта указывает ответ на ваш вопрос.
Любой объект может быть проверен на значение истинности...
и
Все остальные значения считаются истинными, поэтому объекты многих типов всегда верно.
Здесь полный текст документации, (содержимое в скобках, []
, добавляется как дополнение):
5,1. Тестирование ценности истины
Любой объект может быть проверен на значение истины, для использования в if или while условие или как операнд булевых операций ниже. Следующие значения считаются ложными:
-
None
-
False
-
нуль любого числового типа, например, 0
, 0L
, 0.0
, 0j
.
-
любая пустая последовательность, например ''
, ()
, []
.
-
любое пустое отображение, например {}
.
-
экземпляры пользовательских классов, если класс определяет метод __bool__()
[__nonzero__()
в Python 2] или __len__()
, когда этот метод возвращает целое число 0 или значение bool False
. [См. "Модель данных", "Имена специальных методов", раздел "Основная настройка", "Справочник по языку Python" ]
Все остальные значения считаются истинными, поэтому объекты многих типов всегда верно.
Операции и встроенные функции, которые всегда имеют логический результат return 0
или False
для false и 1
или True
для true, если не указано иное заявил. (Важное исключение: логические операции or
и and
всегда верните один из своих операндов.)
Заключение
Так как Exception
не имеет __bool__
, __nonzero__
или __len__
(и не подпадает под другие условия, перечисленные выше), объект Exception
всегда будет тестироваться как True
в булевом контекст.