
Table of Contents(目次)
What is an Error?
Sometimes unexpected problems occur while running a program. These are called "errors." When an error occurs, the program may stop immediately.
Python mainly has two types of errors:
SyntaxError: Occurs when the Python syntax is violated.RuntimeError/Exception: Occurs when the program's syntax is correct, but a problem arises during execution.
As a basic example, let's see what happens when dividing by zero.
x = 10
y = 0
z = x / y # ZeroDivisionError occurs
ZeroDivisionError: division by zero
In this code, dividing by 0 raises a ZeroDivisionError, and the program stops.
Common Types of Errors
Understanding common exceptions in Python and the situations in which they occur helps you quickly identify the cause of errors.
Typical examples:
ZeroDivisionError: Occurs when dividing by 0ValueError: Occurs when trying to convert a string to a number but failingTypeError: Occurs when performing an operation on incompatible types
Sample code:
# Example of ValueError
s = 'abc'
num = int(s) # ValueError occurs
# Example of TypeError
num = 10
text = '5'
result = num + text # TypeError occurs
# Example of ValueError
ValueError: invalid literal for int() with base 10: 'abc'
# Example of TypeError
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Understanding what these exceptions mean allows you to quickly identify the cause.
Catching Exceptions with try/except
The basic way to safely handle exceptions in Python is try/except. If an error occurs inside the try block, it is handled in the except block.
try:
x = 10 / 0
except ZeroDivisionError:
print('Caught ZeroDivisionError: Tried to divide by 0')
Caught ZeroDivisionError: Tried to divide by 0
Note: The ZeroDivisionError raised inside try is caught by except, allowing the program to display an error message without stopping.
Using as e:
By using as e after except, you can assign the exception object to a variable and obtain detailed information.
try:
x = 10 / 0
except ZeroDivisionError as e:
print('Error details:', e)
Error details: division by zero
Using as e allows you to handle not only the type of error but also detailed messages, which is useful for logging and debugging.
Catching Multiple Exceptions
Within a single try block, you can catch multiple exceptions individually.
s = 'abc'
try:
num = int(s)
result = 10 / num
except ValueError:
print('Caught ValueError: Cannot convert string to number')
except ZeroDivisionError:
print('Caught ZeroDivisionError: Tried to divide by 0')
Caught ValueError: Cannot convert string to number
Note: By providing separate except blocks for each exception, you can handle each error appropriately.
Using else and finally
You can add else and finally to a try/except structure.
else: Executed if no exception occursfinally: Always executed, regardless of whether an exception occurs
try:
num = int('10')
except ValueError:
print('ValueError occurred')
else:
print('Conversion successful:', num)
finally:
print('Processing complete')
Conversion successful: 10
Processing complete
Note: else allows grouping actions that succeed, improving readability. finally is useful for cleanup tasks like closing files or network connections.
Exception Handling Inside Functions
Exceptions can also be handled inside functions. You can catch exceptions to safely process them or propagate them to the caller if needed.
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
print('Caught ZeroDivisionError: Tried to divide by 0')
return None
result = safe_divide(10, 0)
print(result)
Caught ZeroDivisionError: Tried to divide by 0
None
Note: Handling exceptions inside functions allows the caller to safely use the function.
Exception Handling Inside Loops
When processing multiple data items, handling exceptions individually inside a loop ensures that one error does not stop the processing of remaining data.
numbers = ['10', '5', 'abc', '0', '8']
total = 0
for s in numbers:
print(f'number {s}:', end='\t')
try:
num = int(s)
total += 10 / num
except ValueError:
print(f'ValueError: "{s}" cannot be converted to a number')
except ZeroDivisionError:
print('ZeroDivisionError: Tried to divide by 0')
else:
print(f'Processed successfully [total = {total}]')
print('Total:', total)
number 10: Processed successfully [total = 1.0]
number 5: Processed successfully [total = 3.0]
number abc: ValueError: "abc" cannot be converted to a number
number 0: ZeroDivisionError: Tried to divide by 0
number 8: Processed successfully [total = 4.25]
Total: 4.25
Note: Handling exceptions inside loops prevents a single data error from stopping the entire process.
Advanced Exercise: Incorporating Exception Handling
An advanced example reads numbers from multiple files and calculates the total. It safely handles missing files or non-numeric data.
When running in Visual Studio Code, create 'numbers1.txt', 'numbers2.txt', and 'numbers3.txt' in the same directory as the Python file and check the results.
file_list = ['numbers1.txt', 'numbers2.txt', 'numbers3.txt']
total = 0
for filename in file_list:
try:
with open(filename, 'r') as file:
data = file.read()
number = int(data)
except FileNotFoundError:
print(f'{filename} not found')
continue
except ValueError:
print(f'Data in {filename} ("{data}") is not a number')
continue
else:
print(f'Successfully read {filename}: {number}')
total += number
print('Total:', total)
Successfully read numbers1.txt: 150
numbers2.txt not found
Data in numbers3.txt ("abc") is not a number
Total: 150
Note: This advanced exercise combines multiple exceptions. Using else groups success processing, and continue moves to the next file.
Exception Class Hierarchy
Python exceptions are organized hierarchically. All exceptions derive from BaseException, and most exceptions we handle are under the Exception class.
See Python: Built-in Exceptions for details on each error.
BaseException
├── BaseExceptionGroup
├── GeneratorExit
├── KeyboardInterrupt
├── SystemExit
└── Exception
├── ArithmeticError
│ ├── FloatingPointError
│ ├── OverflowError
│ └── ZeroDivisionError
├── AssertionError
├── AttributeError
├── BufferError
├── EOFError
├── ExceptionGroup [BaseExceptionGroup]
├── ImportError
│ └── ModuleNotFoundError
├── LookupError
│ ├── IndexError
│ └── KeyError
├── MemoryError
├── NameError
│ └── UnboundLocalError
├── OSError
│ ├── BlockingIOError
│ ├── ChildProcessError
│ ├── ConnectionError
│ │ ├── BrokenPipeError
│ │ ├── ConnectionAbortedError
│ │ ├── ConnectionRefusedError
│ │ └── ConnectionResetError
│ ├── FileExistsError
│ ├── FileNotFoundError
│ ├── InterruptedError
│ ├── IsADirectoryError
│ ├── NotADirectoryError
│ ├── PermissionError
│ ├── ProcessLookupError
│ └── TimeoutError
├── ReferenceError
├── RuntimeError
│ ├── NotImplementedError
│ ├── PythonFinalizationError
│ └── RecursionError
├── StopAsyncIteration
├── StopIteration
├── SyntaxError
│ └── IndentationError
│ └── TabError
├── SystemError
├── TypeError
├── ValueError
│ └── UnicodeError
│ ├── UnicodeDecodeError
│ ├── UnicodeEncodeError
│ └── UnicodeTranslateError
└── Warning
├── BytesWarning
├── DeprecationWarning
├── EncodingWarning
├── FutureWarning
├── ImportWarning
├── PendingDeprecationWarning
├── ResourceWarning
├── RuntimeWarning
├── SyntaxWarning
├── UnicodeWarning
└── UserWarning
Example: ArithmeticError is the parent class of ZeroDivisionError, OverflowError, and FloatingPointError.
Understanding this hierarchy allows you to catch multiple exceptions at once or target specific exceptions.
For example, using the parent ArithmeticError catches all arithmetic-related errors:
try:
x = 10 / 0
except ArithmeticError:
print('An arithmetic error occurred') # ZeroDivisionError is also caught
Conversely, catching only ZeroDivisionError limits the scope:
try:
x = 10 / 0
except ZeroDivisionError:
print('Tried to divide by 0') # OverflowError and FloatingPointError are not caught






