Почему не реализовано правдиво в Python 3? - PullRequest
0 голосов
/ 10 января 2019

Этот вопрос вызван ответами и обсуждениями этого вопроса . Следующий фрагмент кода показывает суть вопроса:

>>> bool(NotImplemented)
True

У меня есть следующие вопросы:

  1. Почему было решено, что bool значение NotImplemented должно быть True? Он чувствует себя не пифонически.
  2. Есть ли веская причина, о которой я не знаю? Документация, кажется, просто говорит, «потому что это так».
  3. Есть ли примеры, где это используется разумным образом?

Причины, по которым я считаю, что это не интуитивно понятно (пожалуйста, не обращайте внимания на отсутствие передового опыта):

>>> class A:
...     def something(self):
...         return NotImplemented
...
>>> a = A()
>>> a.something()
NotImplemented
>>> if a.something():
...     print("this is unintuitive")
...
this is unintuitive

Кажется странным, что что-то с таким отрицательным значением (отсутствием реализации) будет считаться правдивым.

Соответствующий текст от:

NotImplemented

Специальное значение, которое должно возвращаться двоичными специальными методами (например, __eq__(), __lt__(), __add__(), __rsub__() и т. Д.), Чтобы указать, что операция не реализована относительно другого типа; могут быть возвращены двоичными специальными методами на месте (например, __imul__(), __iand__() и т. д.) для той же цели. Его истинное значение истинно.

- Из Документов Python

Редактировать 1

Чтобы прояснить мою позицию, я чувствую, что NotImplemented способность оценивать как логическое значение само по себе является анти-паттерном. Я чувствую, что Исключение имеет больше смысла, но преобладает идея, что постоянный синглтон был выбран из соображений производительности при оценке сравнений между различными объектами. Полагаю, я ищу убедительные причины того, почему этот «путь» был выбран.

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Как уже объяснил принятый ответ , все классы в python считаются истинными (bool(obj) returns True), если они специально не изменяют это с помощью Проверка истинности значения . В некоторых случаях имеет смысл переопределить это, например, пустой список, 0 или False (см. Хороший список здесь ).

Однако нет веских оснований для NotImplemented быть ложным. Это специальное значение, используемое интерпретатором, оно должно возвращаться только специальными методами и не должно достигать обычного кода Python.

Специальное значение, которое должно возвращаться двоичными специальными методами (например, __eq__(), __lt__(), __add__(), __rsub__() и т. Д.), Чтобы указать, что операция не реализована по отношению к другому типу.

Неправильный возврат NotImplemented приведет к вводящему в заблуждение сообщению об ошибке или к возвращению значения NotImplemented в код Python.

Он используется интерпретатором для выбора между методами или для иного влияния на поведение, как в случае с оператором сравнения == или bool() (сначала проверяется __bool__ и затем, если он возвращает NotImplemented, __len__).

Обратите внимание, что существует исключение NotImplementedError, предположительно для случаев, когда на самом деле возникает ошибка, что операция не реализована. В вашем конкретном примере something из class A, вероятно, должно вызвать это исключение.

0 голосов
/ 10 января 2019

По умолчанию объект считается истинным (bool(obj) == True), если только его класс не позволяет переопределить его истинность. В случае NotImplemented никто никогда не предоставлял убедительный сценарий использования для bool(NotImplemented) для возврата False, и поэтому <class 'NotImplementedType'> никогда не предоставлял переопределение.

...