2013-08-16 21 views
6

Byłem (może niesłusznie) myśląc, że operator is robi porównanie id().Co robi operator "jest" w Pythonie?

>>> x = 10 
>>> y = 10 
>>> id(x) 
1815480092 
>>> id(y) 
1815480092 
>>> x is y 
True 

Jednak z val is not None, wydaje się, że to nie jest takie proste.

>>> id(not None) 
2001680 
>>> id(None) 
2053536 
>>> val = 10 
>>> id(val) 
1815480092 
>>> val is not None 
True 

Co robi operator "jest"? Czy to tylko porównanie id obiektów? Jeśli tak, to val is not None jest interpretowane w języku Python jako not (val is None)?

+0

Tak, "val nie jest żadnym" i "not (val jest Brak)" są [odpowiednik] (http://stackoverflow.com/questions/12941287/does-not-e-in-c-differ-from -e-not-in-c-in-python). Ale pierwszy jest bardziej czytelny IMO. –

Odpowiedz

10

Tęskniłeś, że is not to operator też.

bez is, regularne operatora not zwraca wartość logiczną:

>>> not None 
True 

not None jest więc odwrotnością logiczna 'wartości' None. W kontekście logicznym None jest fałszywe:

>>> bool(None) 
False 

tak not None jest logiczna True.

Zarówno None i True są obiektami też, i obie mają adres pamięci (wartość id() powroty dla realizacji CPython Pythona):

>>> id(True) 
4440103488 
>>> id(not None) 
4440103488 
>>> id(None) 
4440184448 

is testy jeśli dwie referencje są skierowane do samego obiektu; jeśli coś jest tym samym obiektem, to samo będzie miało ten sam id(). is zwraca wartość logiczną, True lub False.

is not jest odwrotnością operatora is. Jest to odpowiednik not (op1 is op2), w jednym operatorze. Należy nie być odczytywane jako op1 is (not op2) tutaj:

>>> 1 is not None  # is 1 a different object from None? 
True 
>>> 1 is (not None) # is 1 the same object as True? 
False 
+0

Należy nadmienić, że "nie jest" to pojedynczy operator. 'True to (nie 1) -> False',' True to nie 1 -> True'. To, co zwraca "nie ma żadnych", jest nieistotne. –

+0

@PavelAnossov Zwracana wartość 'not Brak' jest istotna, ponieważ OP użył' (nie None) 'w jednym przykładzie. – delnan

+0

@delnan: dokładnie, ponieważ najwyraźniej OP opuścił to, że 'nie jest' jest pojedynczym operatorem. Wygląda na to, że oczekiwano 'op1 is (not None)'. Który byłby "Fałszywy", a nie "Prawdziwy". –

3

Jako uzupełnienie Martijn Pieters odpowiedź, None, True i False są samotnymi. Jest tylko jedno wystąpienie każdej z tych wartości, dlatego jest bezpieczny w użyciu is je przetestować ..

>>> id(True) 
8851952 
>>> id(False) 
8851920 
>>> id(None) 
8559264 
>>> id(not None) 
8851952 
>>> id(1 == 0) 
8851920 
>>> id(1 == 1) 
8851952 
+0

Dla "Brak" zgadzam się, dla "Fałszywego" i "Prawdziwego" może to być szczegół implementacji. Mimo to testowanie 'if xxx is True 'brzmi dla mnie głupio; zwykłe 'if xxx:' powinno być lepsze. – glglgl

+0

@glglgl Zgadzam się. Właśnie wprowadziłem do dyskusji słowa "prawda" i "fałsz", ponieważ pierwotne pytanie, o którym mowa, brzmi "nie (nie ma)". To znaczy, używając operatora 'is', aby porównać z wartością logiczną' (nie None) '- która nie jest tym samym, co użycie operatora' is not', jak wyjaśniono w innych komentarzach. –

+0

@glglgl można łatwo wymyślić patologiczny przypadek dla 'xxx jest True': zwracane kody błędów, w sposób procesów linuxowych. Jeśli funkcja się powiedzie, zwróci wartość True, jeśli się nie powiedzie, zwróci kod błędu, który może być większy od 0, a zatem również będzie miał wartość true. Wprawdzie jest o wiele lepsze sposoby robienia tego, ale tutaj jesteśmy patologiczni. (Trzeba przyznać, że powyższe dane mają dla czytelnika więcej sensu niż potrzeba "if! Result:" z linux-esque zero-for-success.) – RoadieRich

0

Python próbuje emulować składnię języka angielskiego, aby uczynić go bardziej czytelny dla człowieka, ale w tym przypadku operatora pierwszeństwo jest nieco mylące.

>>> val is not None 
True 

W języku angielskim, pytamy czy val nie posiada wartość, która jest reprezentowana przez tego samego obiektu jako None. W powyższym przykładzie val=10, więc odpowiedź brzmi (poprawnie) True.

Jednak z logicznego, składniowej punktu widzenia masz podziale rachunku słowo w słowo i zakłada się, że jest to:

>>> val is (not None) 
False 

który po załączeniu w odpowiednich patentheses, zwraca swój oczekiwany rezultat (False).

Jako @Martijn Pieters zwraca uwagę, is notis an operator in its own right, i to jedyny operator w pracy tutaj.

Jeśli chciałeś napisać to jako nie dwuznaczny rachunku przy użyciu tylko podmiotom, które nie zawierają spacji, można napisać:

>>> not (val is None) 
True 

Ale to nie jest, jak byś „powiedzieć” zamierzonego komunikatu w języku angielskim, lub nawet napisać to w pseudokodzie.