Dlaczego porównywanie ciągów znaków przy użyciu '==' lub 'is' daje czasami inny wynik?

I've got a Python program where two variables are set to the value 'public'. W wyrażeniu warunkowym mam porównanie var1 is var2, które kończy się niepowodzeniem, ale jeśli zmienię je na var1 == var2, zwraca ono True.

Teraz, jeśli otworzę mój interpreter Pythona i zrobię to samo "is" porównanie, to się powiedzie.

>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True

Czego mi tu brakuje?

Rozwiązanie

is jest testowaniem tożsamości, == jest testowaniem równości. to co dzieje się w twoim kodzie będzie emulowane w interpreterze w ten sposób:

>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False

więc nic dziwnego, że nie są one takie same, prawda?

Innymi słowy: is to id(a) == id(b).

Komentarze (12)

Słowo kluczowe is jest testem tożsamości obiektu, podczas gdy == jest porównaniem wartości.

Jeśli użyjesz is, wynik będzie prawdziwy wtedy i tylko wtedy, gdy obiekt jest tym samym obiektem. Natomiast == będzie prawdziwe za każdym razem, gdy wartości obiektu są takie same.

Komentarze (0)

Myślę, że ma to związek z faktem, że kiedy porównanie 'is' ewaluuje do false, używane są dwa różne obiekty. Jeśli ocenia na true, oznacza to, że wewnętrznie używa tego samego obiektu i nie tworzy nowego, prawdopodobnie dlatego, że stworzyłeś je w ciągu ułamka 2 lub więcej sekund i ponieważ nie ma dużej luki czasowej pomiędzy nimi, jest zoptymalizowany i używa tego samego obiektu.

Dlatego właśnie powinieneś używać operatora równości =, a nie is, aby porównać wartość obiektu łańcuchowego.

>>> s = 'one'
>>> s2 = 'two'
>>> s is s2
False
>>> s2 = s2.replace('two', 'one')
>>> s2
'one'
>>> s2 is s
False
>>> 

W tym przykładzie zrobiłem s2, który był innym obiektem łańcuchowym wcześniej równym 'one', ale nie jest to ten sam obiekt co s, ponieważ interpreter nie użył tego samego obiektu, ponieważ nie przypisałem go początkowo do 'one', gdybym to zrobił, uczyniłby je tym samym obiektem.

Komentarze (2)