I’ve Been Scolded For Using “except Exception as e” in Python Before
^ but isn’t this how the except keyword works?
Yes, but the code can be written better
^ one issue with except Exception as e is that it catches every single Exception, and handles it the exact same way.
The hierarchy of Exceptions
We can check this on our own using the .__subclasses__() method
print(BaseException.__subclasses__())
'''
[<class 'BaseExceptionGroup'>, <class 'Exception'>,
<class 'GeneratorExit'>, <class 'KeyboardInterrupt'>,
<class 'SystemExit'>]
'''
print(Exception.__subclasses__())
'''
[<class 'ArithmeticError'>, <class 'AssertionError'>,
<class 'AttributeError'>, <class 'BufferError'>, <class 'EOFError'>,
<class 'ImportError'>, <class 'LookupError'>, <class 'MemoryError'>,
<class 'NameError'>, <class 'OSError'>, <class 'ReferenceError'>,
<class 'RuntimeError'>, <class 'StopAsyncIteration'>,
<class 'StopIteration'>, <class 'SyntaxError'>, <class 'SystemError'>,
<class 'TypeError'>, <class 'ValueError'>, <class…
<class 'ValueError'>, <class 'Warning'>, ...]
Why is “except Exception as e” problematic?
Using except Exception as e can be problematic because it catches all exceptions derived from Exception, including those you might not intend to handle in the same way. This can mask bugs, make debugging harder, and lead to unintended behavior. For instance, it will catch exceptions like KeyboardInterrupt or SystemExit, which are usually meant to signal that the program should stop running.
Better Exception Handling Practices
1. Be Specific with Exception Types
Instead of catching all exceptions, be specific about the types of exceptions you expect and know how to handle. This makes your code more predictable and easier to debug.
领英推荐
try:
result = some_function()
except ValueError as ve:
print(f"Value error occurred: {ve}")
except TypeError as te:
print(f"Type error occurred: {te}")
2. Use the Finally Block
The finally block can be used to ensure that some code runs no matter what, even if an exception occurs. This is useful for cleaning up resources, such as closing files or network connections.
try:
file = open('example.txt', 'r')
data = file.read()
except FileNotFoundError as fnfe:
print(f"File not found: {fnfe}")
finally:
if file:
file.close()
3. Avoid Bare Except Clauses
Avoid using a bare except clause, which catches all exceptions, including those you don’t intend to catch. Instead, use specific exceptions or at least except Exception.
try:
some_risky_operation()
except Exception as e:
print(f"An error occurred: {e}")
4. Log Exceptions Appropriately
Logging exceptions instead of printing them can be beneficial for debugging and tracking issues in production environments. Python’s logging module is useful for this purpose.
import logging
logging.basicConfig(level=logging.ERROR)
try:
result = risky_operation()
except Exception as e:
logging.error(f"An error occurred: {e}")
Understanding the Exception Hierarchy
To understand the hierarchy of exceptions and which ones to catch, it’s useful to know how exceptions are structured in Python. As mentioned earlier, BaseException is at the top, and most exceptions inherit from Exception. Here’s a visual representation:
BaseException
├── SystemExit
├── KeyboardInterrupt
├── GeneratorExit
└── Exception
├── ArithmeticError
├── AssertionError
├── AttributeError
├── BufferError
├── EOFError
├── ImportError
├── LookupError
├── MemoryError
├── NameError
├── OSError
├── ReferenceError
├── RuntimeError
├── StopIteration
├── SyntaxError
├── SystemError
├── TypeError
├── ValueError
└── Warning
Understanding this hierarchy can help you decide which exceptions to catch and how to handle them appropriately.
Conclusion
While except Exception as e is a valid construct in Python, using it indiscriminately can lead to poor error handling and hidden bugs. By being specific about the exceptions you catch and using best practices, you can write more robust and maintainable code. Remember, good exception handling is not just about catching errors; it’s about handling them in a way that makes your code more resilient and easier to understand.