Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning from caught "RuntimeError" always gives `None` python

So I have a class with two methods in it:

class Test:
    def cycle(self, n=float("inf"), block="x"):
        try:            
            self.cycle(n-1, block)
        except RuntimeError as e:
            if str(e) == "maximum recursion depth exceeded":
                print("... forever")
                return 10
    def f(self):
        try: 
            raise Exception()
        except:
            return 10
        return 20


x = Test()
print(x.cycle())
print(x.f())

and it outputs:

... forever
None
10

What gives? Why can I return from one except and not the other? I can print normally from the first except as well, but it always returns None

like image 259
River Avatar asked Sep 16 '15 03:09

River


1 Answers

Because the method cycle() is recursive, but when you call it recursively you are not returning the result returned by the recursive call.

So inside self.cycle() , lets say you call self.cycle() again, and then in that when trying to call self.cycle() the RuntimeError occurs, so that call returns 10 back to the first self.cycle() call, but this (lets say first self.cycle() ) call does not return this result back to its caller, so the result returned by the second self.cycle() is lost, and you get returned None.

If you return the result of self.cycle() call, you should get correct result. Example -

>>> import sys
>>> sys.setrecursionlimit(3)
>>> class Test:
...     def cycle(self, n=float("inf"), block="x"):
...         try:
...             return self.cycle(n-1, block)
...         except RuntimeError as e:
...             if str(e) == "maximum recursion depth exceeded":
...                 print("... forever")
...                 return 10
...
>>> t = Test()
>>> print(t.cycle())
... forever
10

Please note, I set the recursion limit to 3 so that the recursion depth exceeded error occurs after 3 levels of recursion.

like image 88
Anand S Kumar Avatar answered Nov 15 '22 06:11

Anand S Kumar