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.
