2014-04-05 11 views
9

Dziś dowiedziałem się o is słowo kluczowe w Pythonie i próbowałem następujące:Kiedy, jeśli w ogóle, użyć słowa kluczowego "is" w Pythonie?

>>> x=2+2 
>>> y=4 
>>> x is y 
True 

Zacząłem próbuje is z liczb całkowitych, ponieważ wiedziałem, że odpowiedź byłaby False - tak znalazłem wynik bardzo zaskakujące! Aby podać kontekst, moje tło to C++ i C#, gdzie istnieje rozróżnienie między typami wartości i typami obiektów. W Pythonie, jak teraz rozumiem, wszystko jest typem referencyjnym.

Wydaje się, że powód jest Truex is y jest taka sama, jak wyjaśniono w tej kwestii, How is the 'is' keyword implemented in Python?, który odnosi się do korzystania is z łańcuchów. To znaczy. środowisko wykonawcze zapisuje pamięć poprzez udostępnianie lub "wstawianie" liczb całkowitych dokładnie tak, jak ma to miejsce w przypadku łańcuchów - wyjaśniono to bardziej szczegółowo w odpowiedziach na pytanie: Python “is” operator behaves unexpectedly with integers Znalazłem po moim pierwszym wpisie.

Kolejną rzeczą, która mnie zaskakuje, jest to, że wartość zwracana przez is zależy od implementacji. Co odnosi się do mojego głównego pytania. W zadanym pytaniu o implementację ciągów is w.r.t była dyskusja na temat, kiedy należy użyć is, przy czym kilku użytkowników twierdzi, że (prawie) nigdy z niego nie korzystali. Więc moje pytanie brzmi, kiedy powinno być użyte słowo kluczowe? Jakie są przykłady kanoniczne lub ogólne zasady?

+0

pokrewne: http://stackoverflow.com/questions/13650293/python-is-operator – skamsie

Odpowiedz

15

Powinieneś użyć is, jeśli chcesz wiedzieć, czy dwa obiekty są tym samym obiektem. Nie używaj go, jeśli chcesz się dowiedzieć, czy dwa obiekty mają tę samą wartość o wartości.

Istnieje przykład kanoniczny, ale niestety nie jest to zbyt pomocne. Ludzie powiedzą ci, aby zawsze testować wartość None przy użyciu x is None zamiast x == None. Jednak między tymi przypadkami jest niewielka różnica praktyczna. (Aby uzyskać wyjaśnienie, patrz this question).

W niektórych sytuacjach można zakończyć tworzenie obiektów o tej samej wartości, ale odrębnych obiektach. Na przykład, możesz sobie wyobrazić tworzenie gry wojennej fantasy, w której gracz może magicznie tworzyć sługi, aby walczyć z przeciwnikiem. Więc gracz może stworzyć 100 identycznych orków lub cokolwiek innego. Każdy ork może być reprezentowany przez obiekt i będą one identyczne pod tym względem, że będą miały te same właściwości, ale nadal będą odrębne, ponieważ będzie ich 100 oddzielnych obiektów. Teraz, jeśli przeciwnik spróbuje rzucić zaklęcie "ognistej kuli" na jednym z tych orków, podczas gdy w tej samej turze gracz próbuje rzucić "chroniąc przed ogniem" na orku, możesz sprawdzić, czy cel zaklęcia ognistej kuli is cel zaklęcia ochronnego. Równość nie wystarczy, ponieważ wszystkie orki są równe, ale tylko jeden konkretny orc jest celem każdego czaru i chcesz wiedzieć, czy oba cele są tym samym obiektem. Jest to raczej wymyślny przykład, ale powinien dać szerokie pojęcie o sytuacji, w której możesz skończyć używając is.

14

is testy dla tożsamości, nie równość. Oznacza to, że Python po prostu porównuje adres pamięci obiektu mieszka w”

Istnieje prosta zasada, aby powiedzieć, kiedy użyć == lub jest.

  • == jest dla równości wartości. Użyj go, gdy chcesz wiedzieć, czy dwa obiekty mają tę samą wartość.
  • is jest dla odniesienia równości.Użyj go, gdy chcesz wiedzieć, czy dwa odniesienia odnoszą się do tego samego obiektu.

Ogólnie rzecz biorąc, gdy porównujesz coś do prostego typu, zwykle sprawdzasz równość wartości, więc powinieneś użyć ==.

is zwróci wartość prawda, jeśli dwie zmienne wskazują ten sam obiekt, == jeśli obiekty, do których odnoszą się zmienne, są równe.

>>> a = [1, 2, 3] 
>>> b = a 
>>> b is a 
True 
>>> b == a 
True 
>>> b = a[:] 
>>> b is a 
False 
>>> b == a 
True 

Drugi test działa tylko dlatego, że Python buforuje małych obiektów całkowitą, która jest szczegółów wdrażania. Dla większych liczb całkowitych, to nie działa:

>>> 1000 is 10**3 
False 
>>> 1000 == 10**3 
True 
The same holds true for string literals: 

>>> "a" is "a" 
True 
>>> "aa" is "a" * 2 
True 
>>> x = "a" 
>>> "aa" is x * 2 
False 
>>> "aa" is intern(x*2) 
True 

Uwaga: „Ze względu na automatyczną śmieci zbierania, wolnych list i dynamiczny charakter deskryptorów, można zauważyć, pozornie dziwne zachowanie w pewnych zastosowaniach IS operator, podobnie jak w przypadku porównań między metodami instancji lub stałymi. "

Ze względu na sposób implementacja referencyjna CPython działa, dostaniesz nieoczekiwane i niespójne wyniki, jeśli błędnie stosowanie jest porównanie dla równości odniesienia na liczby całkowite:

>>> a = 500 
>>> b = 500 
>>> a == b 
True 
>>> a is b 
False 

to dość dużo, czego oczekiwaliśmy: a i b mają tę samą wartość, ale są odrębnymi bytami. Ale co z tym?

>>> c = 200 
>>> d = 200 
>>> c == d 
True 
>>> c is d 
True 

Jest to niespójne z wcześniejszym wynikiem. Co tu się dzieje? Okazuje się, że implementacja referencyjna Pythona buforuje obiekty całkowite w zakresie -5..256 jako instancje singleton ze względu na wydajność. Oto przykład, demonstrując w ten sposób:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i))); 
... 
250: True 
251: True 
252: True 
253: True 
254: True 
255: True 
256: True 
257: False 
258: False 
259: False 

Jest to kolejny oczywisty powód, aby nie używać to: zachowanie pozostawia się do wdrożeń kiedy błędnie stosując go do równości wartości.

2

Po pierwsze, jest powodem, że x jest y jest taka sama prawda jak wyjaśniono w tej kwestii, jaki jest „jest” kluczowe realizowane w Pythonie ?, która odnosi się do korzystania z ciągów jest?

Jest podobny. Liczby całkowite od -5 do 256buforowane. Jest to wykorzystywane do celów wydajności.

Moje pytanie brzmi, kiedy należy użyć słowa kluczowego is?

Można użyć is aby sprawdzić, czy dwie referencje są do tego samego obiektu (obiektów sprawdza tożsamość). Ponadto, zaleca się używać is kiedy będzie porównać odniesienie do obiektu z None:

if some_object is None: 
    # ... 
Powiązane problemy