EXCEPTION AND FILE HANDLING IN PYTHON (Section B1)
- UniDrill
- Feb 21
- 6 min read

PART 1: EXCEPTION HANDLING
1.1 Introduction to Errors and Exceptions
While executing a Python program, you may encounter situations where the code does not run at all, generates unexpected output, or behaves abnormally. These issues generally fall into three categories: syntax errors, logical errors, and runtime errors.
Syntax Errors: These are also known as parsing errors. They occur when the programmer does not follow the specific rules or "grammar" of the Python language. For instance, forgetting a parenthesis in a print() statement will trigger a SyntaxError. The Python interpreter detects these before execution; the program will not run until these errors are rectified and saved.
Exceptions: Even if a program is syntactically correct, an error may arise during its execution. For example, trying to divide a number by zero or attempting to open a file that does not exist will disrupt the normal flow of the program. These runtime errors are called exceptions.
An exception is a Python object that represents an error. When an error occurs, an exception is said to have been raised or thrown. If not handled by the programmer, the program will terminate abruptly (crash).
1.2 Built-in Exception Classes
Python’s standard library contains a wide collection of built-in exceptions to deal with common errors. When an exception occurs, the interpreter executes a handler that displays the exception name and the reason for it.
Common Built-in Exceptions include:
SyntaxError: Raised when there is an error in the Python syntax.
ValueError: Raised when a function receives an argument of the correct type but an inappropriate value.
IOError: Raised when an I/O operation (like opening a file) fails.
ZeroDivisionError: Raised when the denominator in a division or modulo operation is zero.
IndexError: Raised when a sequence subscript (index) is out of range.
NameError: Raised when a local or global variable name is not defined.
IndentationError: Raised when there is incorrect indentation.
TypeError: Raised when an operation is applied to an object of an inappropriate type.
OverFlowError: Raised when the result of a calculation exceeds the maximum limit for a numeric data type.
EOFError: Raised when the input() function hits an end-of-file condition without reading any data.
1.3 Raising Exceptions
Exceptions are normally triggered automatically by the interpreter, but they can also be forcefully triggered by the programmer using the raise and assert statements.
The raise Statement: Used to explicitly throw an exception. The syntax is raise exception-name[(optional argument)]. Once raised, the normal flow of the program is interrupted, and the control jumps to the exception handler.
The assert Statement: Used to test a specific condition in the code. It is often used at the start of a function to check for valid input. If the expression following assert evaluates to False, an AssertionError is raised. The syntax is assert Expression[, arguments].
1.4 Handling Exceptions: The Try-Except Clause
Exception handling is the process of writing additional code to provide instructions to the user or take corrective action when an error occurs, preventing the program from crashing.
The Process of Handling: When an error occurs, Python creates an exception object containing the error type, file name, and position. The runtime system then searches the call stack (the list of methods called) to find a suitable block of code to handle the error, a process known as catching the exception.
Syntax of try...except:
try:
# Program statements where exceptions might occur
except [exception-name]:
# Code to handle the specific exception
If an exception occurs in the try block, the remaining statements in that block are skipped, and control transfers to the except block. If no exception occurs, the except block is ignored.
Multiple Except Blocks: A single try block can have multiple except blocks to handle different types of errors specifically.
Default Except: You can use an except clause without specifying an exception name to catch any error not previously handled. This should always be the last clause in the block.
1.5 The else and finally Clauses
The else Clause: This optional block is executed only if no exception was raised in the try block.
The finally Clause: This block is always executed, regardless of whether an exception occurred or was handled. It is commonly used for "cleanup" tasks, such as closing a database connection or a file object. Unlike except, the finally clause does not terminate the exception; if the exception was not caught, it is re-raised after the finally block finishes.
PART 2: FILE HANDLING
2.1 Introduction to Files
In Python, variables have a "lifetime" that lasts only as long as the program is running. To store data permanently for later use, we use files. A file is a named location on a secondary storage medium (like a hard disk) where data is stored permanently.
2.2 Types of Files
All computer files are stored as a series of bytes (binary form), but they are generally classified into two types:
Text Files: These consist of human-readable characters. Examples include .txt, .py, and .csv files. Internally, these characters are stored as bytes using encoding schemes like ASCII or UNICODE. Each line in a text file ends with a special character called End of Line (EOL), which in Python is usually the newline character (\n).
Binary Files: These store actual content like images, audio, or video as a stream of bytes. They are not human-readable; opening them in a text editor will show "garbage" values. Even a single bit change can corrupt a binary file.
2.3 Opening and Closing Files
To work with a file, you must first open it to create a file object (also called a file handle), which acts as a link between the program and the stored data.
• Opening: Use the open() function: file_object = open(file_name, access_mode).
Access Modes:
'r': Read-only (default). Starts at the beginning.
◦ 'w': Write-only. Overwrites existing files or creates a new one. Starts at the beginning.
'a': Append. Adds data to the end of an existing file.
'rb', 'wb', 'ab': Same as above, but for binary files.
'r+', 'w+', 'a+': Modes for both reading and writing.
Closing: Use the close() method: file_object.close(). Closing a file ensures that any data remaining in the buffer is written to the disk and frees up system memory.
The with Clause: This is a preferred way to open files because it automatically closes the file once the block of code is finished, even if an exception occurs.
2.4 Reading from Text Files
There are three primary methods to read data:
1. read(n): Reads n bytes. If n is omitted or negative, it reads the entire file.
2. readline([n]): Reads one complete line, or up to n characters within that line.
3. readlines(): Reads all lines and returns them as a list of strings, where each string ends with \n.
2.5 Writing to Text Files
To write data, the file must be opened in 'w', 'a', or 'r+' mode.
1. write(string): Writes a single string to the file. It returns the number of characters written. Note that you must manually add \n to start a new line. Non-string data must be converted using str() before writing.
2. writelines(list): Used to write multiple strings (from a list or tuple) at once. It does not automatically add newlines between elements.
2.6 Setting Offsets in a File
By default, files are accessed sequentially. To access data randomly, Python provides two methods to manage the file offset (the current position of the file object):
tell(): Returns an integer specifying the current byte position from the beginning of the file.
seek(offset, reference_point): Moves the file object to a specific position.
Offset: Number of bytes to move.
Reference Point: 0 (beginning), 1 (current position), or 2 (end of file). By default, it is 0.
2.7 The Pickle Module (Binary File Handling)
To save complex Python objects like lists, tuples, or dictionaries into a file, Python uses the Pickle module.
Serialization (Pickling): The process of transforming a Python object in memory into a byte stream that can be stored in a binary file.
De-serialization (Unpickling): The inverse process of converting a byte stream back into a Python object.
Pickle Methods:
1. dump(data_object, file_object): Converts the object and "dumps" (writes) it into a file opened in 'wb' mode.
2. load(file_object): "Loads" (reads) the byte stream from a file opened in 'rb' mode and converts it back into a Python object.
When reading multiple records from a binary file using load(), it is common practice to wrap the code in a try...except block to handle the EOFError when the end of the file is reached.
Summary Table: Text vs. Binary Files
Feature | Text File | Binary File |
Content | Human-readable characters (alphabets, numbers) | Stream of bytes (images, executable code) |
Internal Storage | Stored as ASCII/UNICODE values | Stored as raw binary data |
Line Ending | Uses EOL characters (\n) | No specific line delimiters |
Readability | Readable via any text editor | Requires specific software to view |
Module | Handled via standard io functions | Handled via the pickle module |



Comments