8.exception Notes
8.exception Notes
try:
# Code that may raise an exception
except ExceptionType:
# Code to handle the exception
else:
# Code to execute if no exception occurs
finally:
# Code that always runs, regardless of an exception
Exception Handling : 1
program, an exception is raised. If not handled properly, the program crashes.
However, Python provides a structured way to catch and handle these exceptions
to ensure that the program can either recover or at least fail gracefully.
2. Raising Exceptions: You can raise exceptions in your code using the raise
keyword. This is useful when you want to explicitly trigger an error based on
certain conditions.
3. Handling Exceptions: You can handle exceptions using the try , except , else ,
and finally blocks.
4. Custom Exceptions: You can define your own exceptions by creating custom
exception classes.
Raising Exceptions
You can raise exceptions manually in your code using the raise keyword followed
by the exception you want to raise.
Example:
pythonCopy code
def check_age(age):
if age < 18:
raise ValueError("Age must be 18 or older.")
return "Age is valid."
try:
print(check_age(16))
except ValueError as e:
print(f"Error: {e}")
Exception Handling : 2
Exception Hierarchy
All exceptions in Python are derived from the base class BaseException . Some
common exceptions include:
ValueError: Raised when a function gets an argument of the correct type but
with an invalid value.
Syntax:
pythonCopy code
try:
# Code that may raise an exception
except ExceptionType as e:
# Code that runs if the exception occurs
else:
# Code that runs if no exception occurs
finally:
# Code that runs no matter what (optional)
except : Contains code that runs when an exception is raised in the try block.
else : Contains code that runs if no exception is raised in the try block.
Exception Handling : 3
finally: Contains code that always runs, whether an exception was raised or
not (e.g., closing files).
pythonCopy code
try:
num1 = int(input("Enter a number: "))
num2 = int(input("Enter another number: "))
result = num1 / num2
except ZeroDivisionError:
print("Error: Division by zero is not allowed.")
except ValueError:
print("Error: Invalid input. Please enter a valid numbe
r.")
else:
print(f"The result is: {result}")
finally:
print("This block is always executed, whether an exceptio
n occurred or not.")
Multiple Exceptions
You can catch multiple exceptions by specifying them in a tuple.
pythonCopy code
try:
num = int(input("Enter a number: "))
result = 100 / num
except (ValueError, ZeroDivisionError) as e:
print(f"Error: {e}")
Exception Handling : 4
The finally block is used for cleaning up resources, such as closing files or
releasing locks, regardless of whether an exception occurred.
pythonCopy code
try:
f = open('somefile.txt', 'r')
# Some file operations
except FileNotFoundError:
print("File not found.")
finally:
f.close() # Ensures that the file is closed no matter wh
at
Example:
pythonCopy code
class CustomError(Exception):
pass
def check_positive(number):
if number < 0:
raise CustomError("Number must be positive.")
try:
check_positive(-5)
except CustomError as e:
print(f"Custom Error: {e}")
Exception Handling : 5
tryexceptelse
The else block runs only if no exceptions were raised in the try block.
pythonCopy code
try:
result = 10 / 2
except ZeroDivisionError:
print("Cannot divide by zero.")
else:
print("Division successful.")
Example:
pythonCopy code
try:
Exception Handling : 6
try:
num = int(input("Enter a number: "))
result = 10 / num
except ValueError:
print("Invalid input.")
except ZeroDivisionError:
print("Cannot divide by zero.")
2. Use Finally for Cleanup: Use the finally block to clean up resources, such as
closing files or releasing locks.
3. Avoid Overuse of Exceptions: Don't use exceptions for normal control flow;
reserve them for exceptional cases.
4. Log Exceptions: Log exceptions to help with debugging instead of just printing
them.
pythonCopy code
import logging
try:
num = int(input("Enter a number: "))
result = 100 / num
except ZeroDivisionError as e:
logging.error("Attempted division by zero")
except ValueError as e:
logging.error("Invalid input provided")
Exception Handling : 7
Here is a summary table of common Python errors and their descriptions:
Exception Handling : 8
Raised when the result of an Calculating an extremely
OverflowError
arithmetic operation is too large. large exponential.
Raised when an operation runs out Creating a very large list that
MemoryError
of memory. exceeds memory.
NotImplementedError
Raised when an abstract method is Calling an unimplemented
called in a base class. method in a subclass.
1. SyntaxError
Description: Raised when the code contains invalid syntax.
if True
print("This will raise a SyntaxError")
Exception Handling : 9
pythonCopy code
if x = 5: # Should be 'if x == 5:'
print("This will raise a SyntaxError")
2. IndentationError
Description: Raised when the code is not properly indented.
def my_function():
print("This will raise an IndentationError") # This line
should be indented
Example 2:
for i in range(5):
print(i) # Should be indented inside the loop
3. NameError
Description: Raised when a variable or function name is not defined.
Exception Handling : 10
my_function() # This will raise a NameError if 'my_functi
on' is not defined
4. TypeError
Description: Raised when an operation is applied to an object of inappropriate
type.
5. ValueError
Description: Raised when a function receives an argument of the correct type
but inappropriate value.
Exception Handling : 11
import math
result = math.sqrt(-1) # This will raise a ValueError
6. IndexError
Description: Raised when trying to access an index that is out of range in a
sequence (like a list or tuple).
my_list = [1, 2, 3]
print(my_list[5]) # This will raise an IndexError
7. KeyError
Description: Raised when trying to access a key that does not exist in a
dictionary.
Exception Handling : 12
Example 2: Attempting to retrieve a key that isn't present in a dictionary.
8. AttributeError
Description: .
my_string = "Hello"
my_string.append(" World") # This will raise an Attribute
Error
class MyClass:
pass
obj = MyClass()
print(obj.attribute) # This will raise an AttributeError
9. ZeroDivisionError
Description: Raised when attempting to divide by zero.
Exception Handling : 13
Example 2: Performing integer division by zero.
pythonCopy code
result = 10 // 0 # This will raise a ZeroDivisionError
pythonCopy code
from math import nonexistent_function # This will raise a
n ImportError
11. FileNotFoundError
Description: Raised when a file operation fails due to the file not existing.
Exception Handling : 14
Example 2: Reading a file that has been deleted.
import os
os.remove("myfile.txt")
file = open("myfile.txt") # This will raise a FileNotFoun
dError
12. IOError
Description: Raised when an I/O operation fails (e.g., file read/write).
pythonCopy code
file = open("file.txt", "r")
file.close()
file.read() # This will raise an IOError
pythonCopy code
file = open("file.txt", "r")
file.write("Hello") # This will raise an IOError
Type Errors:
Exception Handling : 15
1. Unsupported Operation Between Two Types
In this case, you are trying to use an operation (like + ) between incompatible
types, such as trying to add a string and an integer.
Example:
pythonCopy code
name = "John"
age = 25
print(name + age) # Trying to add a string and an integer.
Output:
pythonCopy code
TypeError: can only concatenate str (not "int") to str
pythonCopy code
print(name + str(age))
Example:
pythonCopy code
name = "John"
print(name()) # Trying to call a string like a function.
Output:
Exception Handling : 16
pythonCopy code
TypeError: 'str' object is not callable
Solution: Remove the parentheses () if you are not trying to call a function.
pythonCopy code
print(name)
pythonCopy code
fruits = ["apple", "banana", "cherry"]
index = "1"
print(fruits[index]) # Using a string as a list index.
Output:
pythonCopy code
TypeError: list indices must be integers or slices, not str
pythonCopy code
print(fruits[int(index)])
Exception Handling : 17
4. Iterating Over a Non-Iterable Object
This happens when you try to loop through an object that can’t be iterated over
(e.g., trying to loop through a number).
Example:
pythonCopy code
number = 12345
for digit in number: # Trying to iterate over an integer.
print(digit)
Output:
pythonCopy code
TypeError: 'int' object is not iterable
Solution: Convert the number to a string (or list) if you want to iterate through its
digits.
pythonCopy code
for digit in str(number):
print(digit)
pythonCopy code
def subtract_numbers(a, b):
return a - b
Exception Handling : 18
result = subtract_numbers("5", 3) # Passing a string instead
of a number.
Output:
pythonCopy code
TypeError: unsupported operand type(s) for -: 'str' and 'int'
Solution: Ensure that the arguments passed to the function are of the correct
type.
pythonCopy code
result = subtract_numbers(int("5"), 3)
Value Error :
What is a ValueError in Python?
A ValueError occurs when a function receives an argument of the correct data
type but an inappropriate or invalid value. It can also happen during unpacking of
iterable objects when there is a mismatch in the number of elements.
1. Invalid Argument
ValueError commonly occurs when you pass an invalid argument to a function. For
example, the float() function can convert a number to a float, but if you pass a
string that cannot be converted, Python raises a ValueError .
Example:
Exception Handling : 19
pythonCopy code
x = 25
y = "abc" # This is an invalid argument for float()
Output:
pythonCopy code
25.0
ValueError: could not convert string to float: 'abc'
pythonCopy code
try:
print(float(x))
print(float(y))
except ValueError:
print("Error: Cannot convert the string to a float.")
pythonCopy code
import math
Exception Handling : 20
print(math.factorial(-5)) # Raises ValueError because the in
put is negative
Output:
pythonCopy code
ValueError: factorial() not defined for negative values
pythonCopy code
import math
n = 3
if n >= 0:
print(math.factorial(n))
else:
print("Error: Factorial is not defined for negative numbe
rs.")
pythonCopy code
my_list = [1, 2, 3]
a, b, c, d = my_list # Trying to unpack 4 values from a list
with only 3 elements
Exception Handling : 21
Output:
pythonCopy code
ValueError: not enough values to unpack (expected 4, got 3)
Solution: Ensure the number of variables matches the number of items in the
iterable.
pythonCopy code
my_list = [1, 2, 3]
a, b, c = my_list # Correct number of variables
print(a, b, c)
index Error:
1. Accessing a Non-Existent Index: This occurs when you try to access an index
that is beyond the valid range of indices for a sequence. Python sequences
are zero-indexed, meaning the first element has an index of 0, the second has
an index of 1, and so on.
Example:
my_list = [1, 2, 4]
print(my_list[4]) # This will raise an IndexError because
Exception Handling : 22
index 4 is out of range.
Output:
2. Empty List: Attempting to access any index in an empty list will raise an
IndexError because there are no elements in the list.
Example:
empty_list = []
print(empty_list[0]) # This will raise an IndexError beca
use the list is empty.
Output:
3.
0.
Example:
my_string = "Example"
print(my_string[-10]) # This will raise an IndexError bec
ause -10 is out of range for this string.
Output:
Exception Handling : 23
pythonCopy code
my_list = [1, 2, 3, 4]
for i in range(len(my_list)):
print(my_list[i])
my_list.pop() # Reduces the list size
Key Errors :
pythonCopy code
my_dict = {'name': 'Alice', 'age': 25}
Explanation: The dictionary my_dict does not have the key 'gender' , so trying
to access it results in a KeyError .
pythonCopy code
my_dict = {'name': 'Alice', 'age': 25}
Exception Handling : 24
# Trying to pop a key that does not exist
my_dict.pop('gender') # KeyError: 'gender'
Explanation: The key 'gender' does not exist in the dictionary, so calling pop()
pythonCopy code
my_dict = {'name': 'Alice', 'age': 25}
4o
Attribute Error :
Exception Handling : 25
Here are some common causes of AttributeError with examples:
Example 1:
X = 10
Output:
plaintextCopy code
Traceback (most recent call last):
File "/path/to/your/script.py", line 5, in <module>
X.append(6)
AttributeError: 'int' object has no attribute 'append'
Exception Handling : 26
# Raises an AttributeError as there is no method 'fst' for st
rings
string = "The famous website is { }".fst("geeksforgeeks")
print(string)
Output:
plaintextCopy code
Traceback (most recent call last):
File "/path/to/your/script.py", line 3, in <module>
string = "The famous website is { }".fst("geeksforgeeks")
AttributeError: 'str' object has no attribute 'fst'
class Geeks:
def __init__(self):
self.a = 'GeeksforGeeks'
# Driver's code
obj = Geeks()
print(obj.a)
Exception Handling : 27
print(obj.b)
Output:
plaintextCopy code
GeeksforGeeks
Traceback (most recent call last):
File "/path/to/your/script.py", line 17, in <module>
print(obj.b)
AttributeError: 'Geeks' object has no attribute 'b'
1. Verify Attribute Names: Ensure that the attribute or method names are correct
and exist for the object you are working with.
2. Check Object Type: Confirm that the object is of the type you expect and that
it supports the attribute or method you are trying to access.
3. Debug and Fix Typographical Errors: Ensure that method names and attribute
references are spelled correctly and use the correct case.
4. Verify Indentation: Check that methods and attributes are correctly defined
with proper indentation in classes.
Name Error :
Exception Handling : 28
A NameError in Python is raised when an identifier (such as a variable or function) is
not defined in the local or global scope. Here are some common causes of
NameError and how to address them:
Example 1:
pythonCopy code
geek = input()
prnt(geek) # Misspelled 'print' as 'prnt'
Output:
plaintextCopy code
NameError: name 'prnt' is not defined
Fix: Ensure that built-in functions and keywords are spelled correctly.
pythonCopy code
geek = input()
print(geek) # Correct spelling
Example 2:
pythonCopy code
geeky = input()
Exception Handling : 29
print(geek) # 'geek' is not defined
Output:
plaintextCopy code
NameError: name 'geek' is not defined
Fix: Make sure that variables are defined before they are used.
pythonCopy code
geek = input()
print(geek) # Correct variable name
pythonCopy code
print(geek) # 'geek' is used before it is defined
geek = "GeeksforGeeks"
Output:
plaintextCopy code
NameError: name 'geek' is not defined
Exception Handling : 30
pythonCopy code
geek = "GeeksforGeeks"
print(geek) # Variable is defined before usage
pythonCopy code
def assign():
geek = "GeeksforGeeks" # Local variable
assign()
print(geek) # 'geek' is not accessible outside the function
Output:
plaintextCopy code
NameError: name 'geek' is not defined
Fix: Ensure that variables are defined in the correct scope where they are
intended to be used. If you need to access a variable globally, define it outside of
any functions or pass it as a parameter.
pythonCopy code
def assign():
global geek
geek = "GeeksforGeeks" # Define 'geek' globally
assign()
Exception Handling : 31
print(geek) # 'geek' is accessible here
Alternative Fix:
pythonCopy code
def assign():
local_geek = "GeeksforGeeks" # Local variable
return local_geek
Exception Handling : 32
Reason: Unhandled errors make it difficult to identify the source of
problems.
Reason: Runtime errors might affect the integrity of data being processed.
5. Security:
In Python exception handling, the execution flow is governed by the presence and
placement of try , except , else , and finally blocks. Here's how each block is
executed and the rules that determine their execution:
1. try Block
Execution: The try block is executed first. This is where you place code
that may raise an exception.
2. except Block(s)
Purpose: To handle specific exceptions that arise from the try block.
3. else Block
Exception Handling : 33
Execution: The else block is executed if no exceptions occur in the try
block.
Purpose: To run code that should only execute if the try block is
successful and does not raise an exception.
4. finally Block
Execution: The finally block is executed after the try , except , and else
Execution Flow:
1. No Exception Raised:
Exception Handling : 34
Purpose of each block :
1. try Block
Purpose:
The try block contains the code that might raise an exception. It’s the section
where you write code that you want to monitor for errors.
Syntax:
pythonCopy code
try:
# Code that may raise an exception
...
Usage:
Place the code that you suspect might cause an error inside the try block.
Use it when you want to handle potential exceptions that might be raised by
this code.
2. except Block
Purpose:
The except block handles exceptions raised by the code in the try block. You can
specify different types of exceptions to handle different errors differently.
Syntax:
pythonCopy code
try:
# Code that may raise an exception
...
except ExceptionType:
# Code to handle the exception
Exception Handling : 35
...
Examples:
pythonCopy code
try:
x = 1 / 0
except ZeroDivisionError:
print("Cannot divide by zero")
try:
data = [1, 2]
print(data[3])
except IndexError:
print("Index out of range")
pythonCopy code
try:
# Code that may raise an exception
value = int("not_a_number")
except ValueError:
print("A ValueError occurred.")
except TypeError:
print("A TypeError occurred.")
Exception Handling : 36
Handles multiple types of exceptions in a single except block:
pythonCopy code
try:
# Code that may raise an exception
value = int("not_a_number")
except (ValueError, TypeError):
print("A ValueError or TypeError occurred.")
Sure! Here's a brief explanation for each case where you might need a try block:
1. User Input
Reason: Users might enter invalid data.
Example: Handling errors when converting input to integers or floats.
pythonCopy code
try:
age = int(input("Enter your age: "))
except ValueError:
print("Invalid input. Please enter a number.")
2. File Operations
Reason: File operations may fail due to file not found, permission issues, etc.
Example: Handling errors when opening or reading a file.
Exception Handling : 37
pythonCopy code
try:
with open('file.txt', 'r') as file:
content = file.read()
except FileNotFoundError:
print("File not found.")
except IOError:
print("Error reading the file.")
3. Network Requests
Reason: Network operations may fail due to connectivity issues or server
errors.
Example: Handling errors when making HTTP requests.
pythonCopy code
import requests
try:
response = requests.get('https://example.com')
response.raise_for_status()
except requests.RequestException as e:
print(f"Network error: {e}")
4. Database Queries
Reason: Database operations may fail due to connection issues or invalid
queries.
Example: Handling errors when connecting to a database or executing a
query.
pythonCopy code
import sqlite3
Exception Handling : 38
try:
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM table")
except sqlite3.DatabaseError as e:
print(f"Database error: {e}")
finally:
conn.close()
5. Type Conversions
Reason: Type conversion operations might fail if the data is not in the
expected format.
pythonCopy code
try:
number = int("not_a_number")
except ValueError:
print("Conversion failed. The input is not a valid num
ber.")
6. Calculations
Reason: Mathematical operations may raise errors, such as division by zero.
pythonCopy code
try:
result = 10 / 0
except ZeroDivisionError:
Exception Handling : 39
print("Cannot divide by zero.")
pythonCopy code
import requests
try:
response = requests.get('https://api.example.com/dat
a')
response.raise_for_status()
except requests.HTTPError:
print("API request failed.")
8. Resource Allocation
pythonCopy code
try:
large_list = [0] * (10**10)
except MemoryError:
print("Memory allocation failed.")
Exception Handling : 40
pythonCopy code
try:
exec("print('Hello'")
except SyntaxError:
print("Error in dynamically executed code.")
pythonCopy code
import json
try:
data = json.loads('{"name": "John", "age": "thirty"}')
except json.JSONDecodeError:
print("Error decoding JSON.")
3. else Block
Exception Handling : 41
Purpose:
The else block runs if no exceptions were raised in the try block. It is useful for
code that should run only if the try block succeeds.
Syntax:
pythonCopy code
try:
# Code that may raise an exception
...
except ExceptionType:
# Code to handle the exception
...
else:
# Code to run if no exception occurs
...
Usage:
Use else for code that should execute only if the try block is successful.
It helps in separating the code that handles exceptions from the code that
should run when no errors occur.
Example:
pythonCopy code
try:
result = 10 / 2
except ZeroDivisionError:
print("Cannot divide by zero")
else:
print(f"Result is {result}")
4. finally Block
Exception Handling : 42
Purpose:
Resource Cleanup
Guaranteed Execution
Finalization Tasks
The finally block contains code that always runs, regardless of whether an
exception occurred or not. It is often used for cleanup actions.
Syntax:
pythonCopy code
try:
# Code that may raise an exception
...
except ExceptionType:
# Code to handle the exception
...
else:
# Code to run if no exception occurs
...
finally:
# Code that always runs
...
Usage:
Use finally for cleanup actions that must occur whether an exception is
raised or not, such as closing files or releasing resources.
Exception Handling : 43
It is executed no matter what happens in the try , except , or else blocks.
Example:
pythonCopy code
try:
file = open("example.txt", "r")
data = file.read()
except FileNotFoundError:
print("File not found")
else:
print("File read successfully")
finally:
file.close() # Ensure the file is closed whether or not
an error occurred
Summary of Usage:
try : Place code that might raise exceptions here.
block syntax :
Example 1: Basic Nesting with try , except , else , and finally
pythonCopy code
try:
print("Outer try block")
try:
x = 10 / 2 # Inner try block
Exception Handling : 44
except ZeroDivisionError:
print("Inner except block: Division by zero")
else:
print("Inner else block: No exception in inner try")
finally:
print("Outer finally block: Always executes")
pythonCopy code
try:
print("Outer try block")
try:
print("Inner try block")
x = 1 / 0 # This will raise a ZeroDivisionError
except ZeroDivisionError:
print("Inner except block")
else:
print("Inner else block")
finally:
print("Inner finally block")
except Exception as e:
print(f"Outer except block: {e}")
finally:
print("Outer finally block")
Exception Handling : 45
your program. Raising exceptions allows you to control the flow of your program
and provide informative error messages.
statement.
Example:
try:
result = divide(10, 0)
except ZeroDivisionError as e:
print(e)
Explanation:
In this example, the
dividefunction raises a ZeroDivisionError if the second parameter is zero. The try
Exception Handling : 46
Example:
def get_age(age):
if age < 0:
raise ValueError("Age cannot be negative!")
return age
try:
age = get_age(-5)
except ValueError as e:
print(e)
Explanation:
In this example, the
get_age function raises a ValueError if the age provided is negative. The try block
catches this exception and prints the error message.
Exception Chaining in Python allows you to handle one exception and then raise a
new exception while preserving the original traceback. This helps in maintaining
the context of the original error while handling or raising a new exception.
Exception Handling : 47
You can use the raise ... from ... syntax to chain exceptions. This syntax
specifies that the new exception was caused by a previous exception.
Example
pythonCopy code
def divide_numbers(a, b):
try:
return a / b
except ZeroDivisionError as e:
raise ValueError("Invalid value for division") from e
try:
result = divide_numbers(10, 0)
except ValueError as e:
print(f"Handled ValueError: {e}")
print(f"Original exception: {e.__cause__}")
class MyCustomError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)
Exception Handling : 48
Using the Custom Exception:
def check_value(x):
if x < 0:
raise MyCustomError("Negative value is not allowed!")
return x
try:
result = check_value(-1)
except MyCustomError as e:
print(f"Error: {e}")
Explanation
Custom Exception Definition: MyCustomError inherits from the base Exception
This example demonstrates how to create a simple custom exception and use it to
handle specific errors in your program.
4o mini
pythonCopy code
class AgeTooYoungError(Exception):
def __init__(self, age):
self.age = age
self.message = f"Age {self.age} is too young. Must be
18 or older."
Exception Handling : 49
super().__init__(self.message)
pythonCopy code
def check_age(age):
if age < 18:
raise AgeTooYoungError(age)
return "Age is valid."
try:
result = check_age(15)
except AgeTooYoungError as e:
print(f"Error: {e}")
else:
print(result)
Exception Handling : 50