bool()
проверяет истинное значение объекта, поэтому вы хотите взглянуть на правила для Проверка истинного значения :
По умолчанию объект считается истинным, если только его класс не определяет метод __bool__()
, который возвращает False
, или метод __len__()
, который возвращает ноль при вызове с объектом.
Вы реализовали только метод __len__
, который намеренно нарушен, подняв TypeError
при вызове. Но bool()
будет вызывать его, когда есть реализация, и нет других доступных опций для определения значения истинности.
При определении значения истинности __bool__
предпочтительнее, чем __len__
:
Когда этот метод не определен, вызывается __len__()
, если он определен, и объект считается истинным, если его результат ненулевой.
Демо-версия:
>>> class Z:
... def __bool__(self):
... return True
... def __len__(self):
... raise TypeError
...
>>> len(Z())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __len__
TypeError
>>> bool(Z())
True
Обратите внимание, что реализация функции len()
вызывает TypeError
, когда реализации для ловушки __len__
нет. Не исключение, что реализация __len__
может поднять, что позволит вам сделать вид, что она на самом деле не реализована, любые исключения, которые она вызывает, распространяются, если она вызывается, потому что вы обычно хотели бы знать, если реализация нарушена каким-то образом.