Porównanie Pythona Brak: czy powinienem używać „is” czy ==?


213

Mój edytor ostrzega mnie podczas porównania my_var == None, ale nie ostrzegam, gdy go używam my_var is None.

Zrobiłem test w powłoce Pythona i ustaliłem, że obie są poprawną składnią, ale mój edytor wydaje się mówić, że my_var is Nonejest to preferowane.

Czy tak jest, a jeśli tak, to dlaczego?


7
PEP 8 mówi gdzieś, że powinieneś porównać do singletonów używających is- python.org/dev/peps/pep-0008/#programming-recommendations
Zmienność

2
Ten plakat mówi o Python 3, a moje pytanie dotyczy Python 2.x. Nie jestem pewien, czy jest to wystarczająco duża różnica, aby uzasadnić oba, ale zredagowałem pytanie, aby na wszelki wypadek to uwzględnić.
Clay Wardell,

2
Nie sądzę, że to pytanie jest naprawdę duplikatem. Drugi dotyczył == vs jest ogólnie, ten dotyczy w szczególności Brak.
IJ Kennedy

Odpowiedzi:


254

Podsumowanie:

Użyj, isgdy chcesz sprawdzić tożsamość obiektu (np. Sprawdzić, czy varjest None). Użyj, ==gdy chcesz sprawdzić równość (np. Czy jest varrówny 3?).

Wyjaśnienie:

Możesz mieć niestandardowe klasy, do których my_var == NonepowróciTrue

na przykład:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

issprawdza tożsamość obiektu . Jest tylko jeden obiekt None, więc kiedy to robisz my_var is None, sprawdzasz, czy to faktycznie ten sam obiekt (nie tylko równoważne obiekty)

Innymi słowy, ==jest sprawdzanie równoważności (która jest definiowana od obiektu do obiektu), podczas gdy issprawdza tożsamość obiektu:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

22
Kiedy się is Noneróżni == None?
Blender

11
@Blender We wspomnianym przypadku. __eq__można zdefiniować w dowolny sposób, ale isnie można tak łatwo zmienić zachowania .
Lev Levitsky

5
@LevLevitsky: Jednym z przykładowych zastosowań Mython było „rozszerzenie protokołów, aby nawet operator mógł zostać przeciążony, nawet is”. Po komentarzu do list zmienił to na „… nawet is(ale tylko jeśli jesteś szalony)”.
abarnert

1
+1, ale byłoby jeszcze lepiej, gdyby ta odpowiedź zawierała odniesienie PEP 8, które robią inni (a także wyjaśnienie, dlaczego decyzja za PEP 8 ma sens, co już ma).
abarnert

3
@abarnert - Nawet nie wiedziałem, że PEP 8 zalecił tutaj. Chodzi o to, że są to różni operatorzy, którzy robią różne rzeczy. Mogą zdarzyć się przypadki, w których object == Nonewłaściwie jest to poprawny idiom (chociaż nie mogę wymyślić żadnego z góry mojej głowy). Musisz tylko wiedzieć, co robisz.
mgilson

127

isjest ogólnie preferowany przy porównywaniu dowolnych obiektów z singletonami, Noneponieważ jest szybszy i bardziej przewidywalny. iszawsze porównuje według tożsamości obiektu, a to, co ==zrobi, zależy od dokładnego rodzaju operandów, a nawet od ich kolejności.

To zalecenie jest wspierane przez PEP 8 , który wyraźnie stwierdza, że „porównań z singletonami takimi jak None należy zawsze dokonywać z operatorami równości islub is notnigdy”.


6
Dzięki za opublikowanie tego; zaakceptowana odpowiedź zawiera kilka interesujących punktów, ale twoja odpowiedź na pytanie jest znacznie bardziej bezpośrednia.
Luke Davis,

Dziwne wydaje się poleganie na szczegółach implementacyjnych. Dlaczego powinno mnie obchodzić, ile jest instancji NoneType?
BallpointBen

@BallpointBen Bo to nie szczegółów wdrażania - istnieje tylko jeden Noneobiekt w ramach globalnego stałej None. Jeśli tak, NoneTypejest to szczegół implementacji, ponieważ Nonesingleton musi mieć jakiś typ. (Fakt, że nie można utworzyć wystąpienia tego typu jest to dobre wskazanie, że jej jedna instancja ma być pojedyncza.)
user4815162342

@BallpointBen Myślę, że kluczową kwestią jest to, że Python ma silną koncepcję tożsamości obiektu. Jeśli chcesz sprawdzić, czy obiekt porównuje równy TO None, za wszelką cenę wykorzystać obj == None. Jeśli chcesz sprawdzić, czy obiekt jest None , użyj obj is None. Istotą zalecenia PEP 8 (i tej odpowiedzi) jest to, że większość ludzi chce tych drugich, gdy chcą sprawdzić Brak, a zdarza się, że jest to szybsze i wyraźniejsze.
user4815162342

Noneróżni się również od obiektów buforowanych, takich jak 0i innych małych liczb całkowitych, gdzie buforowanie jest tak naprawdę szczegółem implementacji. Różnica polega na tym, że liczba całkowita ma wartość wewnętrzną, która nadaje jej właściwości i można ją obliczyć. Z drugiej strony Nonenie ma żadnego stanu , liczy się tylko jego tożsamość .
user4815162342

11

PEP 8 określa, że ​​lepiej jest używać isoperatora podczas porównywania singletonów.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.