Булева идентичность == Истина vs истинна
В стандартном соглашении используется if foo is None
, а не if foo == None
, чтобы проверить, действительно ли значение None
.
Если вы хотите определить, является ли значение точно True
(а не только истинным значением), есть ли причина использовать if foo == True
, а не if foo is True
? Различается ли это между реализациями, такими как CPython (2.x и 3.x), Jython, PyPy и т.д.?
Пример: say True
используется как одноэлементное значение, которое вы хотите отличить от значения 'bar'
или любого другого значения true-like:
if foo is True: # vs foo == True
...
elif foo == 'bar':
...
Есть ли случай, когда использование if foo is True
даст разные результаты от if foo == True
?
ПРИМЕЧАНИЕ. Я знаю Python booleans - если x:, vs, если x == True, vs, если x - True. Тем не менее, он определяет только, следует ли использовать if foo
, if foo == True
или if foo is True
, чтобы определить, имеет ли значение foo
значение true.
ОБНОВЛЕНИЕ: Согласно PEP 285 § Спецификация:
Значения False и True будут одиночными, например None.
Ответы
Ответ 1
Если вы хотите определить, является ли значение в точности True (а не только истинным значением), есть ли какая-то причина для использования, если foo == True, а не if foo is True?
Если вы хотите убедиться, что foo
действительно является логическим значением и значением True
, используйте оператор is
.
В противном случае, если тип foo
реализует свой собственный __eq__()
, который возвращает значение true-ish при сравнении с True
, вы можете получить неожиданный результат.
Как правило, вы всегда должны использовать is
со встроенными константами True
, False
и None
.
Это зависит от реализаций, таких как CPython (2.x и 3.x), Jython, PyPy и т.д.
Теоретически is
будет быстрее, чем ==
, поскольку последний должен соблюдать пользовательские реализации __eq__
типов, тогда как is
может напрямую сравнивать идентификаторы объектов (например, адреса памяти).
Я не знаю исходный код различных реализаций Python наизусть, но я предполагаю, что большинство из них могут оптимизировать это, используя некоторые внутренние флаги для существования магических методов, поэтому я подозреваю, что вы не заметите разница в скорости на практике.
Ответ 2
Никогда не используйте is True
в сочетании с numpy (и производными, такими как pandas):
In[1]: import numpy as np
In[2]: a = np.array([1, 2]).any()
In[4]: a is True
Out[4]: False
In[5]: a == True
Out[5]: True
Это было неожиданно для меня как:
In[3]: a
Out[3]: True
Я думаю, объяснение дается:
In[6]: type(a)
Out[6]: numpy.bool_
Ответ 3
есть ли какая-то причина для использования, если foo == True, а не if foo - True? "
>>> d = True
>>> d is True
True
>>> d = 1
>>> d is True
False
>>> d == True
True
>>> d = 2
>>> d == True
False
Обратите внимание, что bool
является подклассом int
, а True
имеет целочисленное значение 1
. Чтобы ответить на ваш вопрос, если вы хотите проверить, что какая-то переменная "точно True", вам нужно использовать оператор идентификации is
. Но это действительно не pythonic... Могу ли я спросить, каков ваш реальный прецедент - IOW: почему вы хотите сделать разницу между True
, 1
или значением "истины"?
Ответ 4
В большинстве случаев вам не нужно заботиться о такой детали. Либо вы уже знаете, что foo
является логическим (и вы можете использовать if foo
), либо знаете, что foo
- это что-то другое (в этом случае нет необходимости тестировать). Если вы не знаете типы переменных, вы можете захотеть реорганизовать свой код.
Но если вам действительно нужно быть уверенным, что это точно True
и больше ничего, используйте is
. Использование ==
даст вам 1 == True
.
Ответ 5
Вот тест, который позволяет вам увидеть разницу между тремя формами тестирования для True:
for test in ([], [1], 0, 1, 2):
print repr(test), 'T' if test else 'F', 'T' if test == True else 'F', 'T' if test is True else 'F'
[] F F F
[1] T F F
0 F F F
1 T T F
2 T F F
Как вы можете видеть, есть случаи, когда все они дают разные результаты.
Ответ 6
edit: re is True
vs ==
есть случай, и это:
In [24]: 1 is True
Out[24]: False
In [25]: 1 == True
Out[25]: True
также, для одиночных чисел как значения часового, вы можете просто использовать класс
class SentinelTime(object): pass
def f(snth):
if snth is SentinelTime:
print 'got em!'
f(SentinelTime)
вы не хотите использовать if var == True:
, вы действительно хотите if var:
.
Представьте, что у вас есть список. вам неважно, есть ли список "True
" или нет, вы просто хотите узнать, пуст ли он. так что...
l = ['snth']
if l:
print l
проверить это сообщение для оценки False
: Оценка булевых выражений в Python