def divisive_recursion(n):
try:
if n <= 0:
return 1
else:
return n + divisive_recursion(n // divisive_recursion(n - 1))
except ZeroDivisionError:
return -1
finally:
if n == 2:
print("Finally block executed for n=2")
elif n == 1:
print("Finally block executed for n=1")
print(divisive_recursion(5))
Here, divisive_recursion(1)
results in 1 + (1 // divisive_recursion(0))
, then divisive_recursion(0)
returns 1
and it goes into an infinite recursion, where divisive_recursion(1)
and divisive_recursion(0)
gets executed repeatedly. I expected the code to give and RecursionError
due to this, which it does, but the finally
blocks get executed before that somehow, I know that they get executed always but for the prints to be printed n
should be equal to 1
or 2
, which it never does due to the infinite recursion so how come both the print statements are printed when the condition inside them is never evaluated to be True
?
In one of the comments, you ask "does that mean once the program encounters the crash, it will execute all the finally
blocks upward the recursion before it finally crashes".
And the answer is basically "yes".
An exception isn't really a "crash", or perhaps think of it as a controlled way of crashing.
Here is a simple example to illustrate, in this case where the exception is caught and handled:
>>> def foo(n):
... if n == 0:
... raise RuntimeError
... try:
... foo(n - 1)
... except:
... print(f'caught exception at {n=}')
... finally:
... print(f'in finally at {n=}')
...
>>> foo(5)
caught exception at n=1
in finally at n=1
in finally at n=2
in finally at n=3
in finally at n=4
in finally at n=5
And perhaps even more clarifying, here is a case with an uncaught exception:
>>> def foo(n):
... if n == 0:
... raise RuntimeError
... try:
... foo(n - 1)
... except ZeroDivisionError:
... print(f'caught exception at {n=}')
... finally:
... print(f'in finally at {n=}')
...
>>> foo(5)
in finally at n=1
in finally at n=2
in finally at n=3
in finally at n=4
in finally at n=5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in foo
File "<stdin>", line 5, in foo
File "<stdin>", line 5, in foo
[Previous line repeated 2 more times]
File "<stdin>", line 3, in foo
RuntimeError