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
isto compare withNone:var is None. - Use
isto compare withTrueandFalse. However, don't explicitly check forTrueandFalsein conditions, prefer justif user.admininstead ofif user.admin is True. Still, the latter can be useful in tests:assert actual is True. - Use
isinstanceto compare types:if isinstance(user, LoggedInUser). The big difference is that it allows subclasses. So if you have a classAdminwhich is subclass ofLoggedInUser, it will passisinstancecheck. - Use
isin some rare cases when you explicitly want to allow only the given type without subclasses:type(user) is Admin. Keep in mind, thatmypywill refine the type only forisinstancebut not fortype is. - Use
isto 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 thatisbehavior cannot be redefined using magic methods but==can (using__eq__). - Use
==in all other cases. In particular, always use==to compare values:answer == 42.