Почему "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 в булевом контекст.