Both forms below return
True , but what are the consequences for more complex code?
>>> a = '2' >>> a is '2' >>> True >>> a == '2' >>> True
The consequences depend on the purpose of the code.
== are not synonymous, and cannot simply be swapped as if they were.
What happens is that, in many situations, the two return the same value when substituted, giving the erroneous illusion that they behave in the same way, but the nature of the comparisons is completely different.
ischecks whether the two names point to the same object stored in memory
(Maria and Joana live in the same house, so they have the same address)
==compares the content stored under each of the two names, regardless of whether they point to the same object or to different objects.
(Maria's house is identical to José's house, same furniture, same color, etc.)
It is very important that the differences between the two operators are taken into account, so that the code behaves as expected. For this, a slightly more detailed explanation of each one follows:
In Python, the
is operator is the object instance comparer, not values .
>>> x = [2, 3, 4] >>> y = [2, 3, 4] >>> x is y
because although the values are the same, they are completely different objects.
is and strings
Don't be fooled by this example:
>>> x = "string" >>> y = "string" >>> x is y True >>> z = "str"+"ing" >>> a is z True
In this case, despite the impression that the comparison with
is behaves identically to the one made with
== , what is happening here is something else. Python is "smart" enough not to allocate repeated string values multiple times, so it points the new object's name to the previously stored string , effectively leveraging the already allocated data.
Strings should normally be compared to
== unless you know exactly what you are doing.
is and some integers
Look at the following example:
>>> x = 256 >>> y = 256 >>> x is y True >>> x = 257 >>> y = 257 >>> x is y False
This is due to an implementation-driven quirk: when you use numbers from -5 to 256, Python already has an internal storage table whose objects are already created natively and its ID is leveraged.
== is the value comparer, as in most languages. The object can be different, what matters for the comparison is the value:
>>> x = 1278 >>> y = 1278 >>> x == y
If there is a need to debug a situation where the
is does not behave as expected, you can use the
id() function to obtain the internal ID of the objects, as in the following example:
>>> x = 257 >>> y = 257 >>> id(x) 12686128 >>> id(y) 12686140
None is a special object in Python, and represents the absence of a value, somewhat like the
null in some languages. Because this is an absence object, not a value itself, you should always use
x is None and
x is not None , and never
x == None and
x != None .
Attention with this special case:
if ( x is None ):
In this case, a programmer experienced in other languages might be tempted to simply use
if ( x ) , thinking that
None would already be considered false. Just as value comparison should not be used with
None , in
if the verification also requires
is None or
is not None
Implementing class comparison:
The methods that implement the
== comparison in Python are respectively
__eq__ , in which case the programmer should be fully aware of the differences mentioned above. Roughly speaking, it's something along these lines:
# O exemplo foi simplificado demasiadamente ;) class X(object): def __eq__(self, other): return self.value == other def __is__(self, other): return self.value is other