def my_function():
try:
number = int(input("What is your favorite number?\n\n"))
except ValueError: #if anything but an integer was given as the str to input
my_function() #recursive to ask again
return number
my_function()
This throws the exception UnboundLocalError: local variable 'number' referenced before assignment
if I go through the recursive scope at least once and then give a valid input. I thought the variable number should point to a different object every iteration of the function. What am I missing here?
I recognize I can simply move return number
into the try
block to achieve this functionality, but why do I have to?
I thought the variable number should point to a different object every iteration of the function.
What causes the local variable number
to get set in the current call? Answer: number = int(input("What is your favorite number?\n\n"))
. Does it always get assigned? Answer: No, not if int
raises an exception. When does the recursive call happen? Answer: when, and only when, the exception is raised. Therefore, when a recursive call happens, does number
have a value set in the current call? Answer: No.
I recognize I can simply move return number into the try block to achieve this functionality
No; this does not work! If the exception is raised, then return number
does not happen in the current call. The recursive call will occur, and then the value returned from that recursive call will be ignored. In the current call, control flow reaches the end of the function, and None
is returned. You would have to explicitly return
the value from the recursive call, or explicitly assign it to number
and then return
that afterward.
But that's ugly. You should just use a loop for this, like everyone else does.