Czy jest jakaś różnica między:
if foo is None: pass
i
if foo == None: pass
Konwencja, którą widziałem w większości kodu Pythona (i kodu, który sam piszę) jest tym pierwszym, ale ostatnio natknąłem się na kod, który używa tego drugiego. Żadna nie jest instancją (i jedyną instancją, IIRC) typu NoneType, więc to nie powinno mieć znaczenia, prawda? Czy są jakieś okoliczności, w których może to być?
is
operatora nie można dostosować (przeciążony przez klasę zdefiniowaną przez użytkownika).__eq__(self)
jest specjalną wbudowaną metodą, która określa sposób==
obsługi w przypadku użycia na obiekcie Python. Tutaj go zastąpiliśmy, aby po==
zastosowaniu na obiektach typuFoo
zawsze zwracał wartość true. Nie ma równoważnej metody dlais
operatora, więc zachowanieis
nie może być zmienione w ten sam sposób.Możesz przeczytać tę tożsamość i równoważność tego obiektu .
Instrukcja „is” służy do identyfikacji obiektu, sprawdza, czy obiekty odnoszą się do tej samej instancji (ten sam adres w pamięci).
A wyrażenie „==” odnosi się do równości (ta sama wartość).
źródło
a=1;b=1;print(a is b) # True
. Każdy pomysł, dlaczegoa is b
okazuje się być prawdziwy, nawet jeśli wydaje się, że są to 2 różne obiekty (inny adres w pamięci)?Słowo ostrzeżenia:
To nie dokładnie to samo:
Pierwszy z nich jest testem wartości logicznej i może być oceniany na fałsz w różnych kontekstach. Istnieje wiele rzeczy, które reprezentują fałsz w testach wartości boolowskich, na przykład puste pojemniki, wartości boolowskie. W tej sytuacji żaden również nie ocenia się na fałsz, ale robią to również inne rzeczy.
źródło
(ob1 is ob2)
równy(id(ob1) == id(ob2))
źródło
is
wersja nie wymaga wywołania funkcji, a nie python-interpretatora atrybutu odnośnika w ogóle; tłumacz może natychmiast odpowiedzieć, jeśli ob1 jest w rzeczywistości ob2.{} is {}
jest fałszywe iid({}) == id({})
może być (i jest w CPython) prawdziwe. Zobacz stackoverflow.com/questions/3877230Powodem
foo is None
jest preferowany sposób, w jaki możesz obsługiwać obiekt, który definiuje swój własny__eq__
i który definiuje obiekt jako równy Brak. Dlatego zawsze używaj,foo is None
jeśli chcesz sprawdzić, czy jest to nieaktualneNone
.źródło
Nie ma różnicy, ponieważ obiekty, które są identyczne, będą oczywiście równe. Jednak PEP 8 wyraźnie stwierdza, że powinieneś używać
is
:źródło
is
testy tożsamości, a nie równości. Dla twojej instrukcjifoo is none
Python po prostu porównuje adres pamięci obiektów. Oznacza to, że zadajesz pytanie „Czy mam dwie nazwy dla tego samego obiektu?”==
z drugiej strony sprawdza równość określoną__eq__()
metodą. Nie dba o tożsamość.None
jest operatorem singletonu. TakNone is None
jest zawsze.źródło
W przypadku None nie powinno być różnicy między równością (==) a tożsamością (is). NoneType prawdopodobnie zwraca tożsamość dla równości. Ponieważ None jest jedyną instancją, jaką możesz zrobić z NoneType (myślę, że to prawda), dwie operacje są takie same. W przypadku innych typów nie zawsze tak jest. Na przykład:
Spowoduje to wydrukowanie „Równe”, ponieważ listy mają operację porównania, która nie jest domyślnym zwracaniem tożsamości.
źródło
@ Jason :
Nie lubię używać „if foo:”, chyba że foo naprawdę reprezentuje wartość logiczną (tj. 0 lub 1). Jeśli foo jest łańcuchem, obiektem lub czymś innym, „if foo:” może działać, ale dla mnie wygląda to na leniwy skrót. Jeśli sprawdzasz, czy x to Brak, powiedz „jeśli x to Brak:”.
źródło
if foo
zwróci false, a komentarz#foo is None
jest błędny.Kilka dodatkowych szczegółów:
is
Klauzula faktycznie sprawdza czy obaobject
s są w tym samym miejscu pamięci, czy nie. tj. czy oba wskazują na to samo miejsce w pamięci i mają to samoid
.W wyniku 1,
is
zapewnia, czy dwa reprezentowane leksykalnieobject
s mają identyczne atrybuty (atrybuty atrybutów ...), czy nieInstancji z podstawowych typów, takich jak
bool
,int
,string
(z wyjątkiem kilku)NoneType
o tę samą wartość będzie zawsze w tym samym miejscu w pamięci.Na przykład
A ponieważ
NoneType
może mieć tylko jedno wystąpienie w tabeli „zapytań” Pythona, to pierwsze i drugie są bardziej stylem programisty programisty, który napisał kod (być może dla zachowania spójności), a nie mają subtelnego logicznego powodu wybierz jeden nad drugim.źródło
some_string is "bar"
porównywać ciągów NIGDY. NIE JEST JEDEN PRZYCZYNA DO AKCEPTACJI, a ZOSTANIE PRZERWA, gdy się tego nie spodziewasz. Fakt, że często działa, jest po prostu dlatego, że CPython wie, że głupio byłoby stworzyć dwa niezmienne obiekty o tej samej treści. Ale to może się jednak zdarzyć.int
, prawda?Wniosek Johna Machina, który
None
jest singletonem, jest wnioskiem wzmocnionym przez ten kod.Ponieważ
None
jest singletonemx == None
ix is None
miałby ten sam wynik. Jednak moim zdaniem estetycznymx == None
jest najlepszy.źródło
None
obiektem. Dla porównania, rzadkoFalse
zdarza się, aby Żaden nie był używany w żadnym innym kontekście, z wyjątkiem tego, że jest podobny do innych wartości, które są prawdziwe. W takich przypadkach bardziej idiomatyczne jest zrobienie czegoś takiegoif x: pass
źródło