[РЕДАКТИРОВАТЬ: этот вопрос не является дубликатом этого < / а>; Я задаю вопрос о языковом дизайне, т.е. почему это вообще так. Меня не смущает, как оно себя ведет, меня смущает, почему именно это поведение было принято вообще.]

В Python (и некоторых других языках, например, Lua) логические операторы and и or не возвращают логические значения True и False, как можно было бы ожидать, а скорее:

  • x or y: если x ложно, то y, иначе x
  • x and y если x ложно, то x, в противном случае y

Легко видеть, что в частном случае, когда x и y являются логическими значениями, это ведет себя так, как ожидалось.

У меня вопрос: каково собственное оправдание такого обобщения? Я знаю, что вы можете использовать его для таких трюков, как:

foo = x or None

Или тернарный оператор типа DIY, например:

foo = x and y or z

Но я не считаю, что это достаточно веские оправдания для такого удивительного поведения. Всякий раз, когда я вижу, что не-логическое возвращаемое значение используется для его фактического значения (а не в выражении if или чем-то еще, где это не имеет значения в любом случае), мне всегда приходится дважды проверять свое понимание этого, поскольку я всегда забыл, как это работает, и мне нужно снова найти его. Я обычно предпочитаю, чтобы это было написано более обстоятельно. Есть ли фундаментальная причина , почему это должно работать именно так, или это действительно просто для уловок?

-1
dain 9 Окт 2021 в 23:48

2 ответа

Лучший ответ

В случае Python тип bool даже не существовал до более чем десятилетия после того, как язык был выпущен. Если бы он существовал с самого начала, возможно, and и or определялись бы по-другому. Но как бы то ни было, обратная совместимость была гораздо важнее. Из PEP, который представил тип:

Другим следствием требования совместимости является то, что выражение «Истина и 6» имеет значение 6, а выражение «Ложь или Нет» имеет значение Нет. Операторы «и» и «или» используются для возврата первого аргумента, определяющего результат, и это не изменится; в частности, они не заставляют результат быть булевым. Конечно, если оба аргумента являются логическими значениями, результат всегда будет логическим. Его также можно легко заставить быть bool, написав, например, «bool (x and y)».

РЕДАКТИРОВАТЬ: Кстати, изначально Python был предназначен для «преодоления разрыва» между программированием на «богатых данными» языках, таких как C, и «удобных» языках, таких как оболочки Unixy (sh, csh, так далее). Python and и or были больше похожи на && и ||, действующие на языках оболочки, потребляя - слева направо - все и только операнды, необходимые для определения успешности всей цепочки. ("истина") или неудачно ("ложь").

3
Tim Peters 9 Окт 2021 в 21:12

Я могу придумать, по крайней мере, одну вескую причину: он позволяет вам определять пользовательские логические типы, использующие and и or. Вот пример:

from dataclasses import dataclass


@dataclass
class CoolBool:
    value: bool
    note: str

    def __bool__(self):
        return self.value

    def answer(self):
        return "Yes" if self else "No"


print(CoolBool(False, "foo") or CoolBool(True, "bar"))
# -> CoolBool(value=True, note='bar')

Возможно, строковое примечание не особенно полезно, но я думаю, что возможность определять методы в логическом классе, вероятно, пригодится.

0
LeopardShark 9 Окт 2021 в 21:11