When Python runs into a problem it cannot handle on its own, it raises an exception and the program crashes. The except keyword is how you stop that from happening. It gives you a place to catch the error and decide what to do next.
This tutorial covers what an exception is, why Python raises one, what the except keyword does, and how to write a complete try/except block from scratch. Every example is copy-ready and aimed at people who are new to Python.
What is an Exception?
An exception is Python's way of saying "something went wrong at runtime." Unlike a syntax error, which Python spots before the program runs, an exception happens while the code is actually executing. The most common ones beginners encounter are ValueError, TypeError, ZeroDivisionError, and FileNotFoundError.
When Python raises an exception and there is no code in place to handle it, the program stops immediately and prints a traceback. The traceback tells you the type of exception and where it occurred, but it also means your script has crashed.
Every exception in Python is an object. The built-in exceptions like ValueError and ZeroDivisionError all inherit from the base class BaseException. Most user-facing exceptions inherit from Exception, which itself inherits from BaseException.
Before writing a try/except block, intentionally trigger the exception first. Run the code without any error handling, read the traceback, and note the exact exception name. That name is what you put after except.
The example below shows what a crash looks like without except, then what happens when you add it:
# Without error handling — this crashes
number = int("hello") # raises ValueError
print("This line never runs")
Running the code above produces a ValueError: invalid literal for int() with base 10: 'hello' and the script stops. Now compare that to the version with except:
# With error handling — the program keeps running
try:
number = int("hello")
except ValueError:
print("That is not a valid number.")
print("The program continues here.")
Build a valid try/except block that catches a ZeroDivisionError. Click each token in the correct order:
try/except block starts with try:, followed by the code that might fail. Then comes except with the specific exception type — here ZeroDivisionError: because dividing by zero raises that error, not a ValueError. The finally: token is a distractor; it is optional and unrelated to catching the error.
The except Keyword Explained
The except keyword always appears as part of a try/except block. The try clause holds the code that might raise an error. If that error occurs, Python jumps directly to the matching except clause and runs whatever is inside it. If no error occurs, the except clause is skipped entirely.
The structure looks like this:
try:
# code that might raise an exception
risky_operation()
except SomeExceptionType:
# code that runs only if SomeExceptionType was raised
handle_the_error()
You can also capture the exception object using the as keyword, which lets you inspect or log the error message:
try:
age = int(input("Enter your age: "))
except ValueError as e:
print("Input was not a number.")
print("Details:", e)
The variable e is just a name — you could call it anything. Convention is to use e or err. Printing it gives you the exception's message string, which is useful for debugging.
The comparison below shows how the three most common except patterns differ from each other:
- What it catches
- Only
ValueErrorexceptions — for example, passing a non-numeric string toint(). - When to use it
- When you know exactly which exception type your code might raise and you only want to handle that specific case.
- What it catches
- Almost all standard exceptions since most built-in exceptions inherit from
Exception. Does not catchSystemExit,KeyboardInterrupt, orGeneratorExit. - When to use it
- As a broad safety net when you want to log unexpected errors without crashing, while still allowing system-level signals to work correctly.
- What it catches
- Everything — including
SystemExitandKeyboardInterrupt. This means pressing Ctrl+C to stop your script may not work as expected. - When to use it
- Almost never recommended. Using
except Exceptionis the safer alternative for broad catches because it does not swallow system-level signals.
This try/except block has one bug that will prevent it from running correctly. Click the line you think is wrong, then hit check.
except ZeroDivisionError as: to except ZeroDivisionError as e:. When you use as, you must give the exception object a name — the colon alone is not valid syntax. The name e (or any valid identifier) is required after as. If you do not need the exception object at all, simply omit the as clause entirely and write except ZeroDivisionError:.
Catching Multiple Exceptions
A single try block can have several except clauses stacked underneath it. Python checks each one from top to bottom and runs the first one that matches the raised exception. Only one except clause runs per exception — the rest are skipped.
Notice three things in the example below. The expected error cases (ValueError, ZeroDivisionError) print a message and return None explicitly — the caller can then check for None rather than silently receiving it. The broad except Exception clause calls raise with no argument, which re-raises the original exception after logging it. This preserves the full traceback rather than swallowing an unexpected error.
def parse_and_divide(text, divisor):
try:
number = int(text)
result = number / divisor
except ValueError:
print("Could not convert to integer.")
return None
except ZeroDivisionError:
print("Divisor cannot be zero.")
return None
except Exception as e:
print("Unexpected error:", e)
raise # re-raises the original exception unchanged
return result
You can also catch several exception types in a single clause by grouping them in a tuple:
try:
value = int(input("Enter a number: "))
print(10 / value)
except (ValueError, ZeroDivisionError) as e:
print("Invalid input:", e)
Order matters when stacking except clauses. Always put more specific exception types before broader ones. If you put except Exception first, it will catch everything and the specific clauses beneath it will never run.
Beyond except, a full try block can also include an else clause and a finally clause. These are optional but useful. In the example below, open() is called inside a context manager (with) nested inside try. This is the Pythonic approach — the context manager guarantees the file handle is closed when the with block exits, even if an error occurs inside it, so you do not need to call f.close() manually in finally.
try:
with open("data.txt", "r") as f:
file_content = f.read()
except FileNotFoundError:
print("File not found.")
else:
# Runs only if no exception occurred
print(file_content)
finally:
# Always runs — good for cleanup
print("Done.")
How to Use except in Python
These four steps show the complete pattern for writing a try/except block, from the most basic form to a full block with all optional clauses.
-
Write the try block
Open with
try:and indent the code that could raise an exception underneath it. Keep the try block as small as possible — only the code that might fail, not the entire function. -
Add an except clause with a specific exception type
Write
except ExceptionType:at the same indentation level astry:. ReplaceExceptionTypewith the actual exception name — for example,ValueErrororFileNotFoundError. Indent the fallback code beneath it. -
Capture the exception object with as (optional)
Append
as eafter the exception type if you want to inspect the error message. You can then callprint(e)or passeto a logging function to record details about what went wrong. -
Add else and finally if needed
Place an
else:clause after allexceptclauses for code that should run only on success. Place afinally:clause last for cleanup code that must always run — such as closing a file or releasing a lock.
The Zen of Python holds that silent errors are nearly always a mistake — an error worth ignoring is one you have consciously chosen to silence. — Tim Peters, The Zen of Python (PEP 20)
Python Learning Summary Points
- The
exceptkeyword always follows atry:block. It defines the code Python runs when a specific exception type is raised inside the try block. - Specifying the exception type (e.g.,
except ValueError:) is strongly preferred over a bareexcept:. Named exceptions make your intent clear and avoid catching signals likeKeyboardInterruptby accident. - Use
except ExceptionType as e:to capture the exception object. The variableeholds the error message and other details you can log or display. - Multiple
exceptclauses can follow a singletryblock. Python runs the first clause whose type matches and skips the rest. - The optional
elseclause runs only when thetryblock completes without any exception. The optionalfinallyclause always runs regardless of outcome and is used for cleanup.
Exception handling is one of the most practical skills in Python. Once you understand how try and except work together, you can write programs that recover from bad input, missing files, and unexpected runtime conditions — instead of crashing and leaving the user with a traceback.
Frequently Asked Questions
except is a Python keyword that follows a try block. It defines code that runs only when a specified exception occurs inside the try block, letting you handle errors gracefully instead of crashing the program.
A try/except block is a two-part structure. The try clause holds code that might raise an error. The except clause holds the fallback code that Python runs if that specific error occurs.
Yes. You can stack multiple except clauses after a single try block, each targeting a different exception type. Python checks them in order from top to bottom and runs the first one that matches.
A bare except clause with no exception type catches every possible exception, including system-level ones like KeyboardInterrupt and SystemExit. It is generally discouraged because it can hide bugs and make programs hard to debug. Use except Exception as a safer broad catch.
Use the as keyword: except ValueError as e. The variable e holds the exception object and you can display its message with str(e) or print(e).
except ValueError only catches ValueError exceptions. except Exception catches almost all exception types since most built-in exceptions inherit from Exception. Using a specific type is preferred because it makes your intent clear and avoids catching unrelated errors.
The else clause in a try/except block runs only if the try block completed without raising an exception. It is a clean way to separate the success path from the error handling path.
The finally clause runs no matter what — whether the try block raised an exception or not. It is typically used for cleanup tasks such as closing files or releasing connections.
ValueError is the appropriate exception for invalid user input when the type is correct but the value is not acceptable, such as passing a string where a number is expected. TypeError is appropriate when the wrong type is passed entirely.
If no exception occurs, Python skips the entire except block and continues with the rest of the program. The except clause only runs when an exception is raised.