Подражая поведению Python для `len` и` bool` - PullRequest
0 голосов
/ 12 мая 2019

Рассмотрим следующий код:

>>> class X:
... pass
...
>>> x = X()
>>> len(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'X' has no len()
>>> bool(x)
True

Но при попытке подражать этой записи __len__ это не работает.

>>> class Y:
...   def __len__(self):
...     raise TypeError
...
>>> y = Y()
>>> len(y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __len__
TypeError
>>> bool(y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __len__
TypeError

Есть ли способ написать __len__ функцию, которая работает так, как будто она не реализована?

1 Ответ

3 голосов
/ 12 мая 2019

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__ может поднять, что позволит вам сделать вид, что она на самом деле не реализована, любые исключения, которые она вызывает, распространяются, если она вызывается, потому что вы обычно хотели бы знать, если реализация нарушена каким-то образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...