Python exhibits short-circuit evaluation semantics for and
and or
expressions. What that means is that, if the result of the entire expression can be determined from the left-hand-side, then the right-hand-side needn't be evaluated.
False and a
Here, we first evaluate the expression False
(which is a literal and equal to the Python value False
). Now, and
is only true if both sides are true, and we've already found one side which is false. So no matter what a
evaluates to, the result is False
. Hence, we don't evaluate the right-hand-side because it's unnecessary.
Likewise,
True or a
Since True
is truthy and or
only requires one of its arguments to be truthy, whatever a
evaluates to, the result is True
.
This is commonly used to do several veins of error checking in one line. Python doesn't have a null-safe access operator, so we can do the next best thing.
if person is not None and person.salary is not None:
...
Without short-circuit evaluation, the person.salary is not None
would evaluate, even in the case where person
is actually None
, which is an error. We'd have to write the more verbose
if person is not None:
if person.salary is not None:
...
which does nothing for readability.
Likewise, we can use or
to short circuit error conditions.
if person is None or person.salary is None:
raise(MyCustomException("This person doesn't have a job"))
Again, if person
happens to be None
, we don't want person.salary
to evaluate at all, or we'll get an AttributeError
rather than our nice, informative custom exception. Without short-circuiting, we'd have to resort to the much uglier
if person is None:
raise(MyCustomException("This person doesn't have a job"))
if person.salary is None:
raise(MyCustomException("This person doesn't have a job"))