except Exception catches application errors; bare except catches everything including SystemExit and KeyboardInterrupt
In Python 3, every exception derives from BaseException. SystemExit, KeyboardInterrupt, and GeneratorExit are direct subclasses of BaseException, not Exception. except Exception catches only the Exception subtree, so Ctrl+C and sys.exit() still work as expected. A bare except: is equivalent to except BaseException: and will swallow KeyboardInterrupt, SystemExit, and GeneratorExit, which breaks shutdown signals and makes a process unkillable with Ctrl+C. That is the actual reason it is discouraged: it is not about style, it is about keeping the control-flow exceptions that are not application errors out of your handler.
BaseException: SystemExit, KeyboardInterrupt, GeneratorExit, and Exception.
Exception: the branch for ordinary application and library errors. This is what you almost always want.
Catch the narrowest exception you can handle. Catching something you cannot recover from just hides the failure.
Use bare except only in rare cleanup code that must run for any exit reason, and immediately re-raise with raise.
Common mistake: writing except: pass during debugging, which swallows the error and makes root cause invisible.
Common mistake: assuming except Exception catches everything. It does not catch KeyboardInterrupt or SystemExit.
Version note: Python 2 allowed raising old-style strings and had a different hierarchy in some edge cases; the modern hierarchy described here is Python 3.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience