is
The operator is
checks if the two given objects are the same object in the memory:
{} is {} # False
d = {}
d is d # True
Since types are also objects, you can use it to compare types:
type(1) is int # True
type(1) is float # False
type(1) is not float # True
And you can also use ==
for comparing types:
type(1) == int # True
So, when to use is
and when to use ==
? There are some best practices:
- Use
is
to compare withNone
:var is None
. - Use
is
to compare withTrue
andFalse
. However, don't explicitly check forTrue
andFalse
in conditions, prefer justif user.admin
instead ofif user.admin is True
. Still, the latter can be useful in tests:assert actual is True
. - Use
isinstance
to compare types:if isinstance(user, LoggedInUser)
. The big difference is that it allows subclasses. So if you have a classAdmin
which is subclass ofLoggedInUser
, it will passisinstance
check. - Use
is
in some rare cases when you explicitly want to allow only the given type without subclasses:type(user) is Admin
. Keep in mind, thatmypy
will refine the type only forisinstance
but not fortype is
. - Use
is
to compare enum members:color is Color.RED
. - Use
==
in ORMs and query builders like sqlalchemy:session.query(User).filter(User.admin == True)
. The reason is thatis
behavior cannot be redefined using magic methods but==
can (using__eq__
). - Use
==
in all other cases. In particular, always use==
to compare values:answer == 42
.