Definition
raise signals an error on purpose. You can define your own error types by subclassing Exception. Chaining with raise ... from keeps the original cause, so the traceback shows both.
In simple words
Sometimes your code knows that something is wrong, like a negative age. Rather than carrying on with bad data, it stops and says so clearly. Your own exception types are named alarms, so others can respond to exactly the problem they care about.
Why it matters
Failing early with a clear message saves hours of debugging later. Silent bad data in ML can poison a model and you may never notice.
How it works
In code
class BadDataError(Exception):
"""Raised when training data can't be used."""
def load_age(text):
try:
age = int(text)
except ValueError as cause:
raise BadDataError(f"Age isn't a number: {text!r}") from cause
if age < 0:
raise BadDataError(f"Age can't be negative: {age}")
return age
for value in ["25", "-3", "abc"]:
try:
print("OK:", load_age(value))
except BadDataError as error:
print("Rejected:", error, "| caused by:", type(error.__cause__).__name__)Output
OK: 25 Rejected: Age can't be negative: -3 | caused by: NoneType Rejected: Age isn't a number: 'abc' | caused by: ValueError
Common mistakes
- Using a bare except: that catches everything, including KeyboardInterrupt.
- Catching an error and doing nothing. The bug just moves somewhere harder to find.
Check yourself
Summary
- raise stops the program with a clear reason.
- Subclass Exception for your own types.
- Catch specific errors, and never hide them.
Finished reading?
Sources: The Python Tutorial, python.org