Boolean identity = = True vs is True

Jest standardową konwencją, aby używać if foo is None zamiast if foo == None do testowania, czy wartość jest konkretnie None.

Jeśli chcesz określić, czy wartość jest dokładnie True (a nie tylko wartością podobną do prawdy), czy jest jakiś powód, aby używać if foo == True zamiast if foo is True? Czy różni się to między implementacjami, takimi jak CPython (2.x i 3.x), Jython, PyPy itp.?

Przykład: say True jest używany jako wartość Singletona, którą chcesz odróżnić od wartości 'bar', lub jakiejkolwiek innej wartości podobnej do true wartość:

if foo is True: # vs foo == True
    ...
elif foo == 'bar':
    ...

Czy jest przypadek, w którym użycie if foo is True przyniosłoby Inne wyniki niż if foo == True?

Uwaga: jestem świadomy booleans Pythona-if X:, vs if X = = True, vs if X is True. Odnosi się jednak tylko do tego, czy if foo, if foo == True, lub {[6] } powinny być zazwyczaj używane do określenia, czy foo ma wartość podobną do prawdy.


UPDATE: According to PEP 285 § Specification:

Wartości False I True będą singletonami, jak Brak

Author: Community, 2014-12-03

6 answers

Jeśli chcesz określić, czy wartość jest dokładnie prawdziwa (a nie tylko wartość podobna do prawdy), czy jest jakiś powód, aby użyć if foo == True zamiast if foo jest prawdą?

Jeśli chcesz się upewnić, że foo naprawdę jest wartością logiczną i ma wartość True, użyj operatora is.

W przeciwnym razie, jeśli typ foo implementuje własne __eq__(), które zwraca wartość true-ish w porównaniu do True, możesz skończyć z nieoczekiwanym wynikiem.

Jako zasada, należy zawsze używać is z wbudowanymi stałymi True, False i None.

Różni się to w zależności od implementacji, takich jak CPython (2.x i 3.x), Jython, PyPy itp.?

Teoretycznie, is będzie szybszy niż ==, ponieważ ten ostatni musi honorować własne implementacje typów __eq__, podczas gdy is może bezpośrednio porównywać tożsamości obiektów (np. adresy pamięci).

Nie znam kodu źródłowego różnych implementacji Pythona na pamięć, ale Załóżmy, że większość z nich może zoptymalizować to za pomocą niektórych wewnętrznych FLAG dla istnienia magicznych metod, więc podejrzewam, że nie zauważysz różnicy prędkości w praktyce.

 23
Author: Ferdinand Beyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-06 21:18:30

Nigdy nie używaj is True w połączeniu z numpy (i pochodnymi takimi jak pandy):

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

To było dla mnie nieoczekiwane jako:

In[3]: a
Out[3]: True

Wydaje mi się, że wyjaśnienie jest podane przez:

In[6]: type(a)
Out[6]: numpy.bool_
 16
Author: kadee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-10 09:10:17

Czy Jest jakiś powód, aby użyć if foo = = True zamiast if foo jest prawdziwe?"

>>> d = True
>>> d is True
True
>>> d = 1
>>> d is True
False
>>> d == True
True
>>> d = 2
>>> d == True
False

Zauważ, że bool jest podklasą int, a True ma wartość całkowitą 1. Aby odpowiedzieć na twoje pytanie, jeśli chcesz sprawdzić, czy jakaś zmienna "jest dokładnie prawdziwa", musisz użyć operatora tożsamości is. Ale to naprawdę nie jest pythonic... Mogę zapytać, jaki jest twój prawdziwy przypadek użycia-IOW: dlaczego chcesz dokonać różnicy między True, 1 lub jakąkolwiek wartość "prawdy" ?

 8
Author: bruno desthuilliers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-26 14:51:11

Przez większość czasu nie powinieneś dbać o taki szczegół. Albo już wiesz, że foo jest wartością logiczną (możesz więc użyć if foo), albo wiesz, że foo jest czymś innym(w takim przypadku nie ma potrzeby testowania). Jeśli nie znasz typów zmiennych, możesz użyć refaktoryzacji kodu.

Ale jeśli naprawdę chcesz mieć pewność, że jest dokładnie True i nic więcej, Użyj is. Użycie == da ci 1 == True.

 1
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 16:33:31

Oto test, który pozwala zobaczyć różnicę między 3 formami testowania na 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

Jak widać są przypadki, w których wszystkie z nich dają różne wyniki.

 0
Author: Mark Ransom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 16:33:55

edit: re is True vs ==

Jest przypadek, i to jest to:

In [24]: 1 is True
Out[24]: False

In [25]: 1 == True
Out[25]: True

Również, dla singletonów jako wartości sentinel, można po prostu użyć klasy

class SentinelTime(object): pass

def f(snth):
    if snth is SentinelTime:
        print 'got em!'
f(SentinelTime)

Nie chcesz używać if var == True:, naprawdę chcesz if var:.

Wyobraź sobie, że masz listę. nie obchodzi cię, czy lista jest "True", czy nie, po prostu chcesz wiedzieć, czy jest pusta. więc...
l = ['snth']
if l:
    print l

Sprawdź ten post, co ocenia do False: Ocena wyrażeń boolowskich w Python

 0
Author: acushner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:25