Я понимаю, что встроенные типы Python имеют значение "истинность", и пустая строка считается False, а любая непустая строка считается True.

Это имеет смысл

Я могу проверить это с помощью встроенной функции bool.

>>> bool("")
False

>>> bool("dog")
True

Я также могу использовать эти значения истинности при использовании условных выражений. Например:

>>> if "dog":
...     print("yes")
...
yes

Это смущает

Это не работает с оператором ==:

>>> "dog" == True
False

>>> "dog" == False
False

Может кто-нибудь объяснить, почему ==, кажется, действует не так, как условное выражение?

1
Dustin Michels 28 Фев 2018 в 07:09

3 ответа

Лучший ответ

См. тестирование истинного значения и сравнения документации, приведенные ниже.

Короче говоря, большинство вещей по умолчанию правдивы, поэтому bool("dog") верно. Оператор == сравнивает два объекта на равенство, в отличие от сравнения их истинностей, как я полагаю, вы ожидали.

< Сильный > 4,1 . Проверка истинности значения

Любой объект может быть проверен на значение истинности, для использования в условии if или while или в качестве операнда булевых операций ниже.

По умолчанию объект считается истинным, если его класс не определяет либо метод __bool__(), который возвращает False, либо метод __len__() который возвращает ноль, когда вызывается с объектом.

Вот большинство встроенных объектов, которые считаются ложными:

  • константы, определенные как ложные: None и False
  • ноль любого числового типа: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • пустые последовательности и коллекции: '', (), [], {}, set(), range(0)

Операции и встроенные функции, которые всегда имеют логический результат вернуть 0 или False для false и 1 или True для true, если не указано иное заявил . (Важное исключение: логические операции or и and всегда возвращайте один из своих операндов.)

< Сильный > 4,3 . Сравнения

Объекты разных типов, кроме разных числовых типов, никогда не сравниваются одинаково.

...

Неидентичные экземпляры класса обычно сравниваются как неравные если класс не определяет метод __eq__().

2
MarredCheese 28 Фев 2018 в 16:49

Когда вы сравниваете "dog" == True, вы также сравниваете тип этих объектов, а не только их логическое значение.

Теперь, когда True имеет тип bool, а "dog" имеет тип str, они не эквивалентны оператору ==, независимо от того, являются ли их логические значения равны.

Примечание. Здесь проверяются как тип объекта, так и логические значения.

0
Ubdus Samad 28 Фев 2018 в 04:20

Основы

Я полагаю, что ваша путаница может возникнуть из-за сравнения Python с такими языками, как JavaScript, где есть оператор == и ===. Python не работает таким образом.

В Python единственный способ сравнить на равенство с помощью ==, и это сравнивает и значение, и тип.

Таким образом, если вы сравните True == "dog", то выражение будет сразу False, потому что типы bool и str не являются типами, которые можно сравнивать.

Хотя, обратите внимание, что это не значит, что нет типов, которые были бы сопоставимы между собой. Примеры: set и frozenset:

frozenset({1,2,3}) == {1,2,3} # True

Или просто int и float

1 == 1.0 # True

Это поведение для большинства встроенных типов.

Классная часть

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

Например, вы можете сделать это (что, кстати, было отмечено как ужасная идея в комментариях, вы не должны наследовать встроенные типы).

class WeirdString(str):
    def __eq__(self, other):
        return str(self) == str(other) or bool(self) == bool(other)

s = WeirdString("dog")
s == True # True

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

1
Olivier Melançon 28 Фев 2018 в 04:56