Published: 2022-08-16.
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:
is
to compare with None
: var is None
.is
to compare with True
and False
. However, don’t explicitly check for True
and False
in conditions, prefer just if user.admin
instead of if user.admin is True
. Still, the latter can be useful in tests: assert actual is True
.isinstance
to compare types: if isinstance(user, LoggedInUser)
. The big difference is that it allows subclasses. So if you have a class Admin
which is subclass of LoggedInUser
, it will pass isinstance
check.is
in some rare cases when you explicitly want to allow only the given type without subclasses: type(user) is Admin
. Keep in mind, that mypy
will refine the type only for isinstance
but not for type is
.is
to compare enum members: color is Color.RED
.==
in ORMs and query builders like sqlalchemy: session.query(User).filter(User.admin == True)
. The reason is that is
behavior cannot be redefined using magic methods but ==
can (using __eq__
).==
in all other cases. In particular, always use ==
to compare values: answer == 42
.