Module 5: File Handling, Exceptions, and Modularity
Pre-Quiz
Question 1: Which of the following is an immutable type?
a) List
b) Dictionary
c) Tuple
d) Set
Question 2: Which data types can be dictionary keys?
a) Only strings
b) Only numbers
c) Any immutable type
d) Any type including lists
Question 3: If you modify a list that was passed to a function, what happens to the
original list?
a) It remains unchanged
b) It gets modified
c) A copy is created
d) An error occurs
Question 4: How can you get all key-value pairs from a dictionary?
a) [Link]()
b) [Link]()
c) [Link]()
d) [Link]()
Question 5: Which file mode would you use to add content to an existing file without
overwriting it?
a) 'r'
b) 'w'
c) 'a'
d) 'x'
Question 6: Which is NOT a valid file mode?
a) 'r+'
b) 'w+'
c) 'rw'
d) 'a+'
Learn
What is File Handling?
File handling allows programs to read from and write to files on the computer's
storage system. This enables data persistence - the ability to save data beyond the
program's execution and retrieve it later. Files serve as a bridge between volatile
memory (RAM) and permanent storage.
Why File Handling is Important:
1. Data Persistence: Save program data permanently
2. Configuration: Store program settings
3. Logging: Record program activities and errors
4. Data Exchange: Share data between programs
5. Backup: Create copies of important information
6. Large Data: Process data too large for memory
2.1 Understanding File Modes
File Mode Basics:
File modes determine how Python interacts with files. They control whether you can
read, write, or both, and how existing content is handled.
Primary File Modes:
'r' - Read Mode (Default):
Opens file for reading only
File pointer at beginning
Raises error if file doesn't exist
Cannot write to file
Most common for reading existing files
'w' - Write Mode:
Opens file for writing only
Creates new file if doesn't exist
Overwrites existing file (deletes content)
File pointer at beginning
Cannot read from file
'a' - Append Mode:
Opens file for appending
Creates new file if doesn't exist
Preserves existing content
File pointer at end of file
New data added to end
'x' - Exclusive Creation:
Creates new file for writing
Fails if file already exists
Prevents accidental overwriting
Useful for creating unique files
Binary Modes:
Add 'b' to any mode for binary files:
'rb' - Read binary
'wb' - Write binary
'ab' - Append binary
Used for images, videos, executables
Plus Modes (Read and Write):
Add '+' for both reading and writing:
'r+' - Read and write (file must exist)
'w+' - Write and read (overwrites existing)
'a+' - Append and read (preserves content)
Mode Selection Guide:
2.2 Basic File Operations
The open() Function:
The open() function is the gateway to file operations. It returns a file object that
provides methods for reading and writing.
Syntax: file_object = open(filename, mode, encoding)
Parameters:
filename: Path to the file (string)
mode: How to open file (default 'r')
encoding: Text encoding (default system-dependent)
Reading Files:
read() Method:
Reads entire file content as single string:
file = open("[Link]", "r")
content = [Link]()
[Link]()
Optional size parameter:
content = [Link](100) # Read first 100 characters
readline() Method:
Reads one line at a time:
file = open("[Link]", "r")
first_line = [Link]()
second_line = [Link]()
[Link]()
readlines() Method:
Reads all lines into a list:
file = open("[Link]", "r")
all_lines = [Link]()
[Link]()
Each line includes newline character
Writing Files:
write() Method:
Writes string to file:
file = open("[Link]", "w")
[Link]("Hello, World!")
[Link]()
Returns number of characters written
Doesn't add newline automatically
writelines() Method:
Writes list of strings:
file = open("[Link]", "w")
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
[Link](lines)
[Link]()
Doesn't add newlines between items
2.3 The close() Method and File Pointers
Importance of Closing Files:
Closing files is crucial for:
1. Flushing buffers: Ensures all data is written
2. Releasing resources: Frees system resources
3. Preventing corruption: Avoids data loss
4. Allowing access: Other programs can use file
5. Memory management: Prevents memory leaks
File Pointer Concept:
The file pointer tracks the current position in the file:
Starts at beginning for 'r' and 'w' modes
Starts at end for 'a' mode
Moves forward as you read/write
Can be repositioned using seek()
seek() and tell() Methods:
tell(): Returns current file pointer position
position = [Link]()
seek(offset, whence): Moves file pointer
[Link](0) # Move to beginning
[Link](10) # Move to position 10
[Link](0, 2) # Move to end
Whence values:
0: Beginning of file (default)
1: Current position
2: End of file
2.4 Text vs Binary Files
Text Files:
Human-readable content
Character encoding (UTF-8, ASCII)
Line endings handled automatically
Default mode in Python
Examples: .txt, .csv, .py, .html
Binary Files:
Machine-readable content
No encoding conversion
Exact byte representation
Requires 'b' in mode
Examples: .jpg, .pdf, .exe, .mp3
Encoding Considerations:
Always specify encoding for text files:
file = open("[Link]", "r", encoding="utf-8")
Common encodings:
UTF-8: Universal, supports all languages
ASCII: Basic English characters only
Latin-1: Western European languages
UTF-16: Wide character support
Learn2
3.1 Introduction to Context Managers
What is a Context Manager?
A context manager is a Python construct that ensures proper resource management.
It guarantees that cleanup operations happen automatically, even if errors occur. The
'with' statement creates a context where resources are properly acquired and
released.
Why Use Context Managers?
1. Automatic cleanup: Files close automatically
2. Exception safety: Cleanup happens even if errors occur
3. Cleaner code: No need for explicit close() calls
4. Resource management: Prevents resource leaks
5. Best practice: Pythonic way of handling resources
The Problem Without Context Managers:
Traditional file handling risks:
file = open("[Link]", "r")
data = [Link]()
If error occurs here, file never closes!
process_data(data) # Might raise exception
[Link]() # May never execute
3.2 The 'with' Statement
Basic Syntax:
with open(filename, mode) as file_variable:
# File operations here
# File automatically closes when block ends
How It Works:
1. Expression after 'with' is evaluated
2. Result's enter() method is called
3. Return value assigned to variable after 'as'
4. Code block executes
5. exit() method called automatically
6. Cleanup happens even if exception occurs
Example Comparison:
Traditional approach:
file = open("[Link]", "r")
try:
content = [Link]()
process(content)
finally:
[Link]()
Context manager approach:
with open("[Link]", "r") as file:
content = [Link]()
process(content)
File automatically closed here
3.3 Multiple Context Managers
Opening Multiple Files:
You can manage multiple resources in one 'with' statement:
with open("[Link]", "r") as infile, open("[Link]", "w") as outfile:
data = [Link]()
[Link](process(data))
Both files closed automatically
Or nested:
with open("[Link]", "r") as f1:
with open("[Link]", "w") as f2:
[Link]([Link]())
3.4 Context Manager Protocol
Behind the Scenes:
Context managers implement two special methods:
enter(): Called when entering 'with' block
Acquires resource
Returns resource object
Assigned to variable after 'as'
exit(exc_type, exc_value, traceback): Called when leaving block
Releases resource
Handles exceptions if any
Executes even if error occurs
Custom Context Managers:
You can create your own context managers for any resource that needs cleanup:
class ManagedResource:
def enter(self):
# Acquire resource
return self
text
def __exit__(self, exc_type, exc_val, exc_tb):
# Release resource
return False # Don't suppress exceptions
Benefits of 'with' Statement:
1. Guaranteed cleanup: Resources always released
2. Exception handling: Works even with errors
3. Readability: Clear resource boundaries
4. Less code: No explicit cleanup needed
5. Prevents bugs: No forgotten close() calls
Learn3
4.1 Understanding Errors vs Exceptions
Syntax Errors:
Syntax errors occur when Python cannot parse the code. They happen before the
program runs and must be fixed before execution.
Common syntax errors:
Missing colons after if/for/def
Incorrect indentation
Unclosed parentheses/quotes
Invalid variable names
Misspelled keywords
Example syntax errors:
if x > 5 # Missing colon
print("Large")
def function( # Unclosed parenthesis
pass
Exceptions:
Exceptions are errors that occur during program execution. The code is syntactically
correct but encounters a problem at runtime.
Common exceptions:
NameError: Undefined variable
TypeError: Wrong data type
ValueError: Right type, wrong value
IndexError: List index out of range
KeyError: Dictionary key not found
FileNotFoundError: File doesn't exist
ZeroDivisionError: Division by zero
AttributeError: Object lacks attribute
4.2 Exception Hierarchy
Python Exception Structure:
All exceptions inherit from BaseException:
BaseException
├── SystemExit
├── KeyboardInterrupt
├── GeneratorExit
└── Exception
├── StopIteration
├── ArithmeticError
│ ├── ZeroDivisionError
│ ├── OverflowError
│ └── FloatingPointError
├── LookupError
│ ├── IndexError
│ └── KeyError
├── TypeError
├── ValueError
├── IOError
│ └── FileNotFoundError
└── RuntimeError
Why Hierarchy Matters:
Catch specific exceptions first
General exceptions catch descendants
Exception catches most errors
BaseException catches everything
4.3 Try-Except Blocks
Basic Exception Handling:
Structure:
try:
# Code that might raise exception
risky_operation()
except ExceptionType:
# Handle the exception
handle_error()
Multiple Exception Handling:
Handling different exceptions:
try:
file = open("[Link]", "r")
number = int([Link]())
result = 100 / number
except FileNotFoundError:
print("File not found")
except ValueError:
print("Invalid number format")
except ZeroDivisionError:
print("Cannot divide by zero")
Handling multiple exceptions together:
try:
risky_code()
except (ValueError, TypeError):
handle_type_errors()
Catching exception object:
try:
risky_code()
except ValueError as e:
print(f"Error occurred: {e}")
4.4 Else and Finally Clauses
The else Clause:
Executes only if no exception occurs:
try:
file = open("[Link]", "r")
except FileNotFoundError:
print("File not found")
else:
# Runs only if file opens successfully
content = [Link]()
[Link]()
print("File read successfully")
The finally Clause:
Always executes, regardless of exceptions:
try:
file = open("[Link]", "r")
data = [Link]()
except FileNotFoundError:
print("File not found")
finally:
# Always runs, even if exception occurs
print("Cleanup operations")
if 'file' in locals() and not [Link]:
[Link]()
Complete Structure:
try:
# Code that might fail
risky_operation()
except SpecificException:
# Handle specific exception
handle_specific_error()
except GeneralException:
# Handle more general exception
handle_general_error()
else:
# Runs if no exception
success_operations()
finally:
# Always runs
cleanup_operations()
Challenge1:
Code Task: Write a script that opens a file in append mode (a), writes the current
date and time to a new line, and then immediately closes the file using the with
statement.
Challenge2:
Code Task: Write a script that asks the user for a filename, opens it, and prints the
content. Use try...except to gracefully handle a FileNotFoundError if the user
inputs an incorrect name.
Apply1:
Project Task: Create a simple Data Persistence script. Write a function that takes a
list of strings (names) and writes each string to a new line in a file named [Link]
in a single run.
Apply2:
Project Task: Build a Module Importer. Create a separate Python file ([Link])
with a function to calculate a circle's area. Then, import and use this function in the
main script, also using the built-in math module to access $\pi$.
Post-Quiz
Question 1: Which file mode would you use to add content to an existing file without
overwriting it?
a) 'r'
b) 'w'
c) 'a'
d) 'x'
Question 2: What does [Link]() return when called on an empty file?
a) None
b) Empty string ""
c) 0
d) Error
Question 3: What happens if you open a file in 'w' mode and the file already exists?
a) Error is raised
b) Content is appended
c) File is overwritten
d) Creates a backup
Question 4: What character(s) does Python use for newline in text files?
a) \n
b) \r
c) \r\n
d) Depends on operating system
Question 5: How do you properly close a file opened with 'with open()'?
a) [Link]()
b) close(file)
c) No need - closes automatically
d) del file
Question 6: Which is NOT a valid file mode?
a) 'r+'
b) 'w+'
c) 'rw'
d) 'a+'
Question 7: What does [Link] represent?
a) 3.14
b) 3.141592653589793
c) 22/7
d) 3.14159
Question 8: Which method reads one line from a file?
a) [Link]()
b) [Link]()
c) [Link]()
d) file.get_line()
Question9: What type of error occurs BEFORE the program runs?
a) Runtime Error
b) Logical Error
c) Syntax Error
d) Exception
Question 10: Which import statement creates an alias for a module?
a) import numpy to np
b) import numpy = np
c) import numpy as np
d) import numpy -> np