Reputation: 29579
If I have the following:
if a(my_var) and b(my_var):
do something
Can I assume that b()
is only evaluated if a()
is True
? Or might it do b()
first?
Asking because evaluating b()
will cause an exception when a()
is False
.
Upvotes: 4
Views: 183
Reputation: 1123590
b()
will only be evaluated if a(my_var)
is True
, yes. The and
operator short-circuits if a(my_var)
is falsey.
From the boolean operators documentation:
The expression
x and y
first evaluatesx
; ifx
is false, its value is returned; otherwise,y
is evaluated and the resulting value is returned.
You can test this yourself with a function that prints something when called:
>>> def noisy(retval):
... print "Called, returning {!r}".format(retval)
... return retval
...
>>> noisy(True) and noisy('whatever')
Called, returning True
Called, returning 'whatever'
'whatever'
>>> noisy(False) and noisy('whatever')
Called, returning False
False
Python consideres empty containers and numeric 0 values as false:
>>> noisy(0) and noisy('whatever')
Called, returning 0
0
>>> noisy('') and noisy('whatever')
Called, returning ''
''
>>> noisy({}) and noisy('whatever')
Called, returning {}
{}
Custom classes can implement a __nonzero__
hook to return a boolean flag for the same test, or implement a __len__
hook if they are a container type instead; returning 0
means the container is empty and is to be considered false.
On a closely related note, the or
operator does the same thing, but in reverse. If the first expression evaluates to true the second expression will not be evaluated:
>>> noisy('Non-empty string is true') or noisy('whatever')
Called, returning 'Non-empty string is true'
'Non-empty string is true'
>>> noisy('') or noisy('But an empty string is false')
Called, returning ''
Called, returning 'But an empty string is false'
'But an empty string is false'
Upvotes: 7
Reputation: 60004
With the wonderful help of help()
(hah):
>>> help('and')
Boolean operations
******************
or_test ::= and_test | or_test "or" and_test
and_test ::= not_test | and_test "and" not_test
not_test ::= comparison | "not" not_test
...
The expression ``x and y`` first evaluates *x*; if *x* is false, its
value is returned; otherwise, *y* is evaluated and the resulting value
is returned.
...
So yes, if a(my_var)
returns False, then the function b
will not be called.
Upvotes: 1
Reputation: 1006
The compiler always reads top to down and left to right. So If False and True
then False is encountered first by the compiler and it exits the if condition. This is valid for all softwares that I know of.
Upvotes: 0
Reputation: 1013
Yup, it is safe to do that. Pythons if conditions are lazily evaluated.
Upvotes: 1