Skip to main content

Python Try Except

When writing Python programs, errors are inevitable. Whether it's user input that doesn't match what you expect, a file that doesn't exist, or a network connection that fails, your program will encounter situations that disrupt its normal flow. This is where exception handling with try-except blocks becomes crucial.

What is Exception Handling?

Exception handling is a mechanism that separates error-handling code from regular code. It allows a program to continue running even when errors occur, rather than crashing abruptly.

In Python, the primary tool for exception handling is the try-except block.

Basic Syntax of Try-Except

python
try:
# Code that might cause an exception
# This is where you put operations that could fail
except:
# Code that executes if an exception occurs
# This is where you handle the error

Let's break down how this works:

  1. The code inside the try block is executed.
  2. If no exception occurs, the except block is skipped.
  3. If an exception occurs in the try block, Python immediately jumps to the except block.
  4. After executing the except block, the program continues running.

A Simple Example

Here's a basic example that handles division by zero:

python
try:
result = 10 / 0 # This will cause a ZeroDivisionError
print(result)
except:
print("Error: Division by zero!")

# Output:
# Error: Division by zero!

Without the try-except block, this would crash your program with:

ZeroDivisionError: division by zero

Catching Specific Exceptions

The previous example catches any exception, which isn't always desirable. It's better to catch specific exceptions to handle different error types differently:

python
try:
number = int(input("Enter a number: "))
result = 10 / number
print(f"10 divided by {number} is {result}")
except ZeroDivisionError:
print("Error: You can't divide by zero!")
except ValueError:
print("Error: You must enter a valid number!")

# Example Input/Output 1:
# Enter a number: 0
# Error: You can't divide by zero!

# Example Input/Output 2:
# Enter a number: hello
# Error: You must enter a valid number!

# Example Input/Output 3:
# Enter a number: 5
# 10 divided by 5 is 2.0

Multiple Exception Types

You can also handle multiple exception types with a single except block:

python
try:
# Code that might raise either a ValueError or TypeError
value = int("abc") # This will cause a ValueError
except (ValueError, TypeError):
print("Error: There was a problem with the value or type!")

Getting Exception Information

To get information about the exception, you can assign it to a variable:

python
try:
file = open("nonexistent_file.txt", "r")
content = file.read()
except FileNotFoundError as error:
print(f"Error: {error}")
# You can also access error attributes
print(f"Error type: {type(error).__name__}")

# Output:
# Error: [Errno 2] No such file or directory: 'nonexistent_file.txt'
# Error type: FileNotFoundError

The Else Clause

You can add an else clause that executes when no exception occurs:

python
try:
number = int(input("Enter a positive number: "))
if number <= 0:
raise ValueError("The number must be positive")
except ValueError as error:
print(f"Error: {error}")
else:
print(f"You entered the valid number: {number}")

# Example Input/Output 1:
# Enter a positive number: 5
# You entered the valid number: 5

# Example Input/Output 2:
# Enter a positive number: -3
# Error: The number must be positive

The Finally Clause

The finally clause executes regardless of whether an exception occurred or not. It's perfect for cleanup operations:

python
try:
file = open("example.txt", "w")
file.write("Hello, World!")
# Some other operations that might raise an exception
except IOError:
print("Error: Could not write to the file")
finally:
file.close() # This always executes, ensuring the file is closed
print("File has been closed")

Raising Exceptions

Sometimes, you want to raise exceptions in your code when certain conditions are met:

python
def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
print(f"Age set to {age}")

try:
set_age(-5)
except ValueError as error:
print(f"Error: {error}")

# Output:
# Error: Age cannot be negative

Real-World Example: Validating User Input

Here's a practical example of using try-except for validating user input:

python
def get_valid_age():
while True:
try:
age = int(input("Please enter your age: "))
if age <= 0:
raise ValueError("Age must be positive")
if age > 120:
raise ValueError("Age seems unrealistic")
return age
except ValueError as e:
if str(e) == "invalid literal for int() with base 10":
print("Please enter a numeric value for age")
else:
print(f"Invalid input: {e}")

# Usage:
try:
user_age = get_valid_age()
print(f"Valid age entered: {user_age}")
except KeyboardInterrupt:
print("\nInput cancelled by user")

Real-World Example: Working with Files Safely

Exception handling is crucial when working with external resources like files:

python
def read_file_safely(filename):
try:
with open(filename, 'r') as file:
return file.read()
except FileNotFoundError:
print(f"Warning: The file '{filename}' was not found.")
return None
except PermissionError:
print(f"Warning: No permission to read '{filename}'.")
return None
except Exception as e:
print(f"Unexpected error reading '{filename}': {e}")
return None

content = read_file_safely("config.txt")
if content:
print("File content loaded successfully")
else:
print("Using default configuration instead")

Best Practices for Using Try-Except

  1. Be specific: Catch specific exceptions rather than using a bare except: clause.
  2. Keep it focused: Put only the code that might raise the exception inside the try block.
  3. Don't silence errors: Handle exceptions meaningfully, don't just pass or print a generic message.
  4. Use finally for cleanup: Ensure resources are properly managed regardless of exceptions.
  5. Document your exceptions: Make it clear which exceptions your functions might raise.

Common Python Exceptions

Here are some common Python exceptions you might encounter:

  • SyntaxError: Invalid syntax in your code
  • IndentationError: Incorrect indentation
  • NameError: Using a variable or function name that doesn't exist
  • TypeError: Operation on an inappropriate type
  • ValueError: Operation receives a value of the correct type but inappropriate value
  • ZeroDivisionError: Dividing by zero
  • FileNotFoundError: Attempting to access a non-existent file
  • IndexError: Trying to access an index that doesn't exist
  • KeyError: Trying to access a dictionary key that doesn't exist
  • AttributeError: Trying to access an attribute that doesn't exist

Summary

Exception handling with try-except blocks is a powerful tool in Python that allows you to:

  • Catch and respond to errors gracefully
  • Prevent your program from crashing
  • Provide meaningful feedback to users
  • Safely work with external resources like files and networks
  • Handle different types of errors in different ways

By mastering exception handling, you'll write more resilient Python code that can handle unexpected situations elegantly.

Exercises

  1. Write a program that asks the user for two numbers and prints the result of dividing the first by the second. Handle all possible exceptions.

  2. Create a function that reads a CSV file and returns its contents as a list. Use exception handling to deal with file errors.

  3. Implement a simple calculator that can add, subtract, multiply and divide. Use exception handling to deal with invalid inputs and operations.

  4. Write a program that tries to connect to a website and handles possible network errors.

Additional Resources

Happy coding, and remember that exceptions are not always exceptional – they're a normal part of robust code!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)