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?
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)
.
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.
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.