The following code is expected to set the nonlocal variable flag
to true after 3 calls to recur()
. I expect flag
in the following code to be always true after recur(2)
returns (starting from 0)
def f():
flag = False
def recur(n):
nonlocal flag
print(f"this is recur {n}")
print("flag is: ", flag)
if n == 2:
print(f"end of recur {n}")
print("flag is: ", flag)
return True
flag = flag or recur(n 1) # the culprit line
print(f"end of recur {n}")
print("flag is: ", flag)
return False
recur(0)
f()
However, flag
jumps from true to false when recur(1) returns. The output of the function is as follow:
this is recur 0
flag is: False
this is recur 1
flag is: False
this is recur 2
flag is: False
end of recur 2
flag is: False
end of recur 1
flag is: True
end of recur 0
flag is: False <-- I expect this to be true
When I change the culprit line to flag = recur(n 1) or flag
, the code works as expected, i.e. flag
will always be true after recur(2) returns.
I suspect it has something to do with short-circuiting of or
, but still I am totally confused. Please help.
CodePudding user response:
In flag = flag or recur(n 1)
, the LHS of the or
is evaluated before recur(n 1)
. When recur(0)
executes this line, it evaluates flag
and gets False
before calling recur(1)
.
By the time recur(1)
returns, flag
is True
, but the LHS of the or
has already been evaluated, so the or
evaluates False or False
and gets False
, not True
.
Short-circuiting would also come into play if the LHS of the or
was evaluated as True
, but that never happens in this code.