DEV Community

Discussion on: Python exceptions considered an anti-pattern

Collapse
 
yawpitch profile image
Michael Morehouse

But, this except ZeroDivisionError will still execute. And it looks like goto mark to me.

But that's your apparent misunderstanding... it doesn't behave at all like a goto ... like not even within the same ballpark.

This:

try:
    return n / d
except ZeroDivisionError:
    return foo()
Enter fullscreen mode Exit fullscreen mode

Is fundamentally no different than:

if not d:
    return foo()
return n / d
Enter fullscreen mode Exit fullscreen mode

And adding in a deeper level of function nesting doesn't change that ... this:

def div(n, d):
    return n / d

try:
    return div(n, d)
except ZeroDivisionError:
    return foo()
Enter fullscreen mode Exit fullscreen mode

Is now fundamentally no different than:

if not d:
    return foo()
return div(n, d)
Enter fullscreen mode Exit fullscreen mode

The exception handler is effectively just a convenient way of writing the boilerplate for whatever test(s) would be required in that if to satisfy any given exception state, with the added benefit of deferring the test until an actual exception state has been encountered and needs to be addressed (or allowed to bubble further up the stack).

If you're writing the exception handler there's no magic (and certainly nothing that resembles a goto; you're reacting to a specific exception that has happened below you and the traceback tells you precisely where that came from ... if your reaction is to call a function then you know precisely where the control flow goes to and also that it will always return to you, even if it returns to you in the form of another exception (like for instance a SystemExit you've wrapped in the response function). A goto is a completely arbitrary escape from normal control flow, an exception is not, it's entirely predictable, though I'll happily admit it's not always easy to predict.

If no exception handling is involved then the behaviour is very predictable: where the exception is raised the stack frame exits and bubbles up a level. In each successively higher frame in which it's not handled it's effectively the same as catching it and immediately re-raising it, and so it continues to bubble ... when it hits the surface the interpreter catches it, prints the traceback, and shuts down in an orderly fashion with a non-zero returncode.

I don't have an issue with you wanting to make error handling a bit more sane for yourself, especially if you're going to try to enforce type constraints, but comparison to goto is just incorrect.