A few examples will make it more obvious:
In [7]: foo = 1000
In [8]: bar = 1000
In [9]: foo is bar # same value but different objects so identity test is False
Out[9]: False
In [10]: foo == bar # equality test is True
Out[10]: True
In [11]: id(foo) # both have different id's
Out[11]: 41007616
In [12]: id(bar)
Out[12]: 40841432
In [13]: foo = bar # now make foo point to the object bar
In [14]: foo is bar # now foo is bar so identity check is True
Out[14]: True
In [15]: id(bar) # matching id's
Out[15]: 40841432
In [16]: id(foo)
Out[16]: 40841432
To compare values use ==
to check identity use is
Something to be aware of is e small integers -5
to 256
and strings are cached and reused in python so if you assign a = 10
and b = 10
,they actually both point to the same object so a is b
.
In [20]: a = 256
In [21]: b = 256
In [22]: a is b
Out[22]: True
In [23]: a = 257
In [24]: b = 257
In [25]: a is b
Out[25]: False
In [26]: foo = "foo"
In [27]: bar = "foo"
In [28]: foo is bar
Out[28]: True
In [29]: foo = "$bar"
In [30]: bar = "$bar"
In [31]: foo is bar # now False because it does not start with an _ or a letter
Out[31]: False
strings are only cached if they start with an underscore
or a letter
and contain only letters
, numbers
or underscores
:
A final example of why is __main__
fails:
# first __main__ object inside locals dict, second is just a string __main__
print id(locals()['__name__']),id("__main__")
print (locals()['__name__']) is "__main__" # so not the same object
print (locals()['__name__']) == "__main__" # but == strings
if __name__ == "__main__":
print id(locals()['__name__']), id(__name__ ) # same id's
print (locals()['__name__']) is __name__ ) # same object stored in locals
140168071262544 140168071262592
False
True
140168071262544 140168071262544
True