#post
Preventing vs Handling Errors in Python
I keep seeing feedback that it’s not Pythonic to validate invariants before trying an operation (i.e. LBYL, look before you leap, tiger style, guard clauses). That it’s more Pythonic to just try and then handle anything that goes wrong (i.e. EAFP, easier to ask forgiveness than permission).
Intuitively, I look before I leap. And I find defensive programming styles like Tiger Style appealing.
So what’s the deal, Pythonistas? Why so reckless? Why do you want to waste CPU time running that code that may be destined to fail?
Benefits of EAFP (try/except) imo:
- you can potentially make your code more informative by identifying the exact errors that are possible to encounter
- e.g.
except KeyError
is at least as informative isif "key" in dict:
- e.g.
- your code will run fast if it takes the happy path more often than the error path (by not having to run the guard condition logic)
Downsides of EAFP imo:
- try/except always indents your code, while guards don’t need to if you return early and keep the happy path on left
Why should the language you’re using dictate your coding style?
Stuff to read:
- EAFP and LBYL coding styles | Pydon’t 🐍 | mathspp
- points out when EAFP runs faster (minimizes code that has to run when success is more likely than failure) and is more self-documenting that a potentially complex guards (when naming the errors is more description than checking preconditions)
- LBYL vs EAFP: Preventing or Handling Errors in Python – Real Python
- Ask for Forgiveness or Look Before You Leap?
- Idiomatic Python: EAFP versus LBYL - Python
- Look Before You Leap vs Easier to Ask For Forgiveness Than Permission in Programming | by Agus Richard | Nerd For Tech | Medium
- In Python, Don’t Look Before You Leap | by Kamran Ahmad | Better Programming
- Programming with Python: Defensive Programming - advocates assertions, to be used as function pre/post conditions to check invariants (i.e. what must be true at start/end of function body) + TDD to confirm input/output pairs match expectations
- Defensive Programming — Lesson 8 - 10m video advocating using inline asserts as preconditions checking inputs at the start of a function + postconditions checking function output at the end of the function (though he seems not to notice that those assertions at the end are unreachable given his early returns) + writing unit tests first