0% found this document useful (0 votes)
27 views53 pages

Advanced Programming in Python Lecture 6

This document covers exception handling in Python, explaining its importance for managing errors during program execution to ensure reliability and user-friendly feedback. It details the structure of try-except blocks, the types of built-in exceptions, and the creation of user-defined exceptions for specific application needs. The document concludes by connecting exception handling to file handling, emphasizing the need for error management in file operations.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views53 pages

Advanced Programming in Python Lecture 6

This document covers exception handling in Python, explaining its importance for managing errors during program execution to ensure reliability and user-friendly feedback. It details the structure of try-except blocks, the types of built-in exceptions, and the creation of user-defined exceptions for specific application needs. The document concludes by connecting exception handling to file handling, emphasizing the need for error management in file operations.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

LECTURE 7

🔹 Exception Handling in Python


Exception handling in Python is the mechanism that allows a program to deal
with unexpected problems during execution. In real-world applications, errors
are normal — users may enter invalid input, files may not exist, network
connections may break, and so on. Instead of letting the program crash,
Python gives us tools to detect, manage, and recover from errors gracefully.

Error-handling ensures:

 The program does not stop suddenly

 Users receive meaningful feedback

 System resources like files and network connections are safely closed

 The program can continue running even after something goes wrong

Exception handling makes software more robust, reliable, and safe.

🔹 What Is an Exception?
An exception is an event that interrupts the normal flow of a program. It
occurs when Python encounters a situation it cannot handle automatically.

Examples of situations that cause exceptions:

 Dividing a number by zero

 Converting invalid text to integer

 Accessing invalid list index

 Opening a file that does not exist

 Providing the wrong type of input

Whenever these events occur, Python generates an Exception Object,


which contains information about the error.
✔ Example — Program Crash Without Exception Handling

🔹 Why Do We Need Exception Handling?

Exception handling is essential because:

1. Programs Should Not Crash

Applications in real life (ATMs, banking software, online stores, games) must
continue running even when something goes wrong.

2. To Provide User-Friendly Messages


3. To Protect Data

Exception handling prevents data corruption during file writing, database


updates, or network transfers.

4. To Ensure Resources Are Released

Files, networks, and memory must be closed or freed properly even if an


error happens.

5. To Make Debugging Easier

Python can tell you exactly what went wrong and where.

🔹 How Python Handles Errors Internally


When an error is detected, Python performs the following steps:

1. Stops executing current instructions

2. Creates an Exception Object

3. Looks for a matching except block

4. If not found → program terminates and prints traceback

This process shows why try–except blocks are necessary.


🔹 The try–except Structure

The basic method for handling exceptions is the try–except block.

This prevents the program from crashing.

🔹 Handling Specific Exceptions


Catching all exceptions with a single except: block is possible, but it is not
considered good practice.
It hides real issues.

Instead, we catch specific exceptions.

✔ Example
try:

value = int(input("Enter a number: "))

except ValueError:

print("Please enter valid digits!")

Why this is better:

 Provides accurate error messages

 Makes debugging easier

 Keeps program behavior predictable

🔹 Multiple except Blocks

A single block of code can produce different kinds of errors.


We can handle them separately:

✔ Example

try:

x = int(input("Enter number: "))

y = int(input("Enter divisor: "))

print(x / y)

except ValueError:

print("Only numbers are allowed.")

except ZeroDivisionError:

print("Division by zero is not allowed.")

This is used heavily in professional software.

🔹 Using one except block for multiple exceptions

Python allows grouping exceptions using parentheses:


✔ Example

try:

number = int("abc")

except (ValueError, TypeError):

print("Invalid input type or value.")

🔹 The else Block

The else block runs only if no exception occurs.

This is useful when you want some code to execute only when everything is
successful.

✔ Example

try:

n = int(input("Enter age: "))

except ValueError:

print("Please enter a valid number.")

else:

print("You entered:", n)

🔹 The finally Block


The finally block always runs — with or without an exception.
It is used for cleanup operations:

 Closing files

 Closing network connections

 Releasing system resources

 Resetting states

✔ Example

try:
f = open("[Link]")

except FileNotFoundError:

print("File not found.")

finally:

print("Execution complete.")

🔹 Full try–except–else–finally Structure


This is the most robust format used in real applications.

✔ Example

try:

file = open("[Link]", "r")

content = [Link]()

except FileNotFoundError:

print("The file does not exist.")

else:

print("File read successfully!")

print(content)

finally:

print("Closing program.")

The flow is:

 try → risky work

 except → handle error

 else → only on success

 finally → executes always


🔹 How This Connects to Next Topic
We now understand:

 How exceptions occur

 How they are handled

 How to use try, except, else, and finally

 Why exception handling is critical

Now we can move smoothly into the next major part:

👉 Built-In Exceptions
Where we study the actual error types available in Python, such as:

 ValueError

 TypeError

 IndexError

 ZeroDivisionError

 FileNotFoundError

 and many more

These exceptions will help us write more accurate and controlled error
handling.

🔷 Built-in Exceptions in Python


Now that we understand what exceptions are and how Python handles them,
the next step is to explore the built-in exceptions Python provides. These
exceptions represent common error situations that occur during program
execution.
Python automatically raises these exceptions when something goes wrong,
and we can catch them using except blocks.

Built-in exceptions make debugging easier because:

 They describe the error clearly

 They indicate exactly what went wrong


 They allow us to write more specific error-handling code

 They prevent us from catching unnecessary or unrelated errors

Built-in exceptions are defined inside Python’s standard library and inherit
from the base class Exception.

🔹 Categories of Built-in Exceptions


Python’s built-in exceptions span multiple types of problems:

 Arithmetic errors (ZeroDivisionError, OverflowError)

 Type and value errors (TypeError, ValueError)

 Input/output errors (FileNotFoundError, PermissionError)

 Lookup errors (IndexError, KeyError)

 Import errors (ImportError, ModuleNotFoundError)

 Syntax and indentation errors (SyntaxError, IndentationError)

 Attribute and name errors (AttributeError, NameError)

Let’s go through each important one with explanations and examples.

🔷 1. Zero Division Error


Occurs when a number is divided by zero — mathematically impossible and
undefined.

✔ Explanation

Python immediately raises this error if you try to divide by zero during
runtime.

✔ Example

try:

result = 10 / 0

except ZeroDivisionError:

print("You cannot divide by zero.")


🔷 2. Value Error
Occurs when a function receives a valid type but an invalid value.

✔ Explanation

Means:
“You passed me the right kind of data, but the data itself is wrong.”

✔ Example

try:

num = int("hello")

except ValueError:

print("Cannot convert text to an integer.")

🔷 3. Type Error
Occurs when an operation is applied to an object of an inappropriate type.

✔ Example

try:

print("Age: " + 25)

except TypeError:

print("Cannot add a string and integer.")

🔷 4. Name Error
Raised when you try to use a variable that has not been defined.

✔ Example

try:

print(age)

except NameError:

print("Variable is not defined.")


🔷 5. Index Error
Occurs when accessing an index that does not exist in a list.

✔ Example

try:

items = [1, 2, 3]

print(items[5])

except IndexError:

print("List index out of range.")

🔷 6. Key Error
Occurs when accessing a dictionary key that is not present.

✔ Example

try:

data = {"name": "John"}

print(data["age"])

except KeyError:

print("Key does not exist in the dictionary.")

🔷 7. File Not Found Error


Raised when a requested file is missing.

✔ Example

try:

f = open("[Link]")

except FileNotFoundError:

print("File not found on system.")


🔷 8. Permission Error
Occurs when you try to access a file or directory without proper permission.

✔ Example

try:

f = open("/system/[Link]", "w")

except PermissionError:

print("You do not have permission to write this file.")

🔷 9. Attribute Error
Occurs when an attribute or method does not exist for an object.

✔ Example

try:

x = "hello"

[Link]("!")

except AttributeError:

print("String objects have no append() method.")

🔷 10. Import Error / Module Not Found Error


Occurs when Python cannot find the module you are trying to import.

✔ Example

try:

import nonexistent

except ModuleNotFoundError:

print("Module does not exist.")


🔷 11. Syntax Error
Occurs when Python detects incorrect code structure.
This is a compile-time error, not runtime.

✔ Example

try:

eval("if True print('hi')")

except SyntaxError:

print("Syntax is incorrect.")

🔷 12. Indentation Error


Occurs when code indentation is incorrect — Python requires strict
indentation.

✔ Example

code = """

def test():

print('Hello')

"""

try:

exec(code)

except IndentationError:

print("Code indentation is incorrect.")

🔷 13. Overflow Error


Occurs when the result of an arithmetic operation is too large to handle.

✔ Example

try:

import math
[Link](1000)

except OverflowError:

print("Number too large to calculate.")

🔷 14. Runtime Error


Raised when an error cannot fit into any other category.

✔ Example

try:

raise RuntimeError("Something went wrong")

except RuntimeError as e:

print(e)

🔷 15. Stop Iteration Error


Occurs when no more items are available in an iterator.

✔ Example

try:

it = iter([1, 2])

print(next(it))

print(next(it))

print(next(it))

except StopIteration:

print("No more items in iterator.")

🔷 Connecting to Next Topic


Now we understand built-in exceptions, which Python automatically provides.
But what if:
 You are building a banking system and want to raise
InvalidBalanceError

 You are creating a login system and want to raise


PasswordTooShortError

 You are developing a game and want to raise OutOfEnergyError

For such custom situations, Python allows you to create your own
exceptions.

🔷 User-Defined Exceptions
Built-in exceptions are useful for common problems, but many programs
need to handle application-specific errors. These are errors that Python
cannot predict because they are unique to your program’s logic.

For example:

 A banking app may need InsufficientBalanceError

 A school system may need InvalidGradeError

 A hotel reservation system may need RoomNotAvailableError

 A login system may need WeakPasswordError

When such situations occur, we raise custom exceptions that describe the
problem more accurately than generic built-in exceptions.

User-defined exceptions make code more readable, maintainable, and


professional.

🔹 Why Do We Need User-Defined Exceptions?

Built-in exceptions like ValueError or TypeError do not always convey the


exact meaning of your problem.

Consider this example:


 A user tries to withdraw more money than available in their bank
account

 Python will NOT raise any built-in exception (because mathematically


subtraction is valid)

But logically, this is an error.

This requires a custom exception such as:

InsufficientBalanceError

Custom exceptions help with:

✔ Accurate error messages

✔ Clear problem identification

✔ Clean structure in large software

✔ Better debugging

✔ Following real-world business rules

🔷 Creating a Custom Exception Class


Custom exceptions are created using class definitions that inherit from
Python’s built-in Exception class.

✔ Basic structure

class CustomException(Exception):

pass

This creates a new exception type that behaves like a normal Python error.

🔷 Example: Creating and Raising a Simple Custom


Exception
Code:

class InvalidAgeError(Exception):

pass
age = 14

if age < 18:

raise InvalidAgeError("Age must be at least 18.")

Output:

InvalidAgeError: Age must be at least 18.

This shows your custom exception working just like built-in exceptions.

🔷 Adding Custom Messages to Exceptions


You can include detailed messages for clearer understanding.

Example:

class PasswordTooShortError(Exception):

pass

password = "abc"

if len(password) < 6:

raise PasswordTooShortError("Password must be at least 6 characters


long.")

Custom messages help the user understand what they did wrong.

🔷 Using Custom Exceptions with try–except


User-defined exceptions are handled the same way as built-in ones.

Example:

class NegativeMarksError(Exception):

pass
try:

marks = -10

if marks < 0:

raise NegativeMarksError("Marks cannot be negative.")

except NegativeMarksError as e:

print("Error:", e)

Output:

Error: Marks cannot be negative.

This is useful in systems like school management or grading software.

🔷 Creating More Structured Custom Exceptions


Larger applications often require more detail.
We can create exceptions with:

 Custom attributes

 Additional data

 Methods inside exception class

Advanced Example:

class WithdrawalError(Exception):

def __init__(self, balance, amount):

[Link] = balance

[Link] = amount

super().__init__(f"Cannot withdraw {amount}. Balance available:


{balance}")

try:

balance = 500
amount = 800

if amount > balance:

raise WithdrawalError(balance, amount)

except WithdrawalError as e:

print(e)

Output:

Cannot withdraw 800. Balance available: 500

This shows how custom exceptions can hold extra information.

🔷 Raising Custom Exceptions Inside Functions


Just like built-in exceptions, custom exceptions can be raised from inside
functions to signal incorrect behavior.

Example:

class InvalidEmailError(Exception):

pass

def check_email(email):

if "@" not in email:

raise InvalidEmailError("Email must contain '@' symbol.")

return True

try:

check_email("[Link]")

except InvalidEmailError as e:

print("Email error:", e)

Output:

Email error: Email must contain '@' symbol.


This technique is used in form validation systems.

🔷 When to Use User-Defined Exceptions


Use custom exceptions when:

 You want an error message that clearly describes a specific application


problem

 Built-in exceptions don’t fit the scenario

 You want to enforce business rules (banking, booking, login, inventory


systems)

 You want cleaner, readable code

 You are developing a large system with multiple modules

Not every program needs custom exceptions, but they become essential in
bigger systems.

🔷 Connecting to Next Topic

Now you understand:

 How Python provides built-in exceptions

 Why custom exceptions are needed

 How to create your own exception classes

 How to raise and handle them

 How they help large-scale software

This completes the entire concept of Exception Handling.

The next part of your syllabus connects naturally to:

👉 File Handling

Because file handling often creates many exceptions such as:

 File not found

 Permission denied

 Unable to write file


 Unexpected end of file

 File in use

So exception handling and file handling work closely together.

🔷 File Handling in Python


After understanding exceptions, the next essential part of Python
programming is file handling. File handling allows programs to store data
permanently, read information, write logs, manage documents, and interact
with the operating system. Almost every real-world application relies on files
— from databases and settings to user-uploaded content.

Python provides a simple and powerful interface to work with files through
the built-in open() function and additional modules like os and pathlib.

Exception handling and file handling often work together, because file
operations are prone to errors (e.g., missing files, incorrect paths, permission
issues). That is why this topic naturally follows exception handling.

🔷 What Is File Handling?


File handling refers to the process of:

 Opening files

 Reading files

 Writing to files

 Creating new files

 Updating or appending data

 Closing files

 Managing directories and paths

Python supports both:

 Text files (.txt, .csv, .log)


 Binary files (.jpg, .exe, .mp4)

File handling ensures long-term data storage, unlike variables that disappear
when the program ends.

🔷 Why File Handling Is Important?

✔ Real-world tasks require permanent storage

For example:

 Saving user accounts

 Storing logs

 Keeping application settings

 Writing reports

 Creating audit trails

✔ Communication between programs

Files let programs exchange data without direct connection.

✔ Backup and recovery

Files preserve information even when a program crashes.

✔ Automation systems

Scripts often read from files (configurations) and write outputs.

Because of the importance of file handling, Python provides clear and


consistent tools for reading and writing files.

🔷 The open() Function


Python’s built-in open() function is used to create a connection between the
program and a file.

✔ Syntax

file_object = open("filename", "mode")

✔ Meaning:

 "filename" → the file to open


 "mode" → the operation you want to perform

🔷 File Modes in Python


The mode defines how you want to access the file.
Below are the most important modes:

Mod Description
e

"r" Read (default)

"w" Write — overwrites file

"a" Append — adds new data


at end

"x" Create — error if exists

"b" Binary mode

"t" Text mode (default)

"r+" Read + write

"w+ Write + read (overwrites


" file)

🔷 Reading Files in Python


Reading files is one of the most common file-handling tasks.
To read any file, you must:

1. Open the file

2. Read its content

3. Process the data

4. Close the file

(We will later use with to auto-close.)

🔹 Reading an Entire File (read())


This method reads the whole content of the file at once.

✔ Example

Suppose [Link] contains:

Hello, Python!

This is a sample file.

Code:

f = open("[Link]", "r")

content = [Link]()

print(content)

[Link]()

Output:

Hello, Python!

This is a sample file.

🔹 Reading Line by Line (for loop)


This is efficient for large files.

✔ Example

f = open("[Link]", "r")

for line in f:

print([Link]()) # strip removes newline

[Link]()

🔹 Using read line()


Reads one line at a time.
✔ Example:

f = open("[Link]")

line1 = [Link]()

line2 = [Link]()

print(line1, line2)

[Link]()

🔹 Using read lines ()


Returns a list of all lines.

✔ Example:

f = open("[Link]", "r")

lines = [Link]()

print(lines)

[Link]()

Output:

['Hello\n', 'Welcome to Python\n']

🔷 Why Closing Files Is Important


When Python opens a file, it consumes system resources.
If you don’t close files:

 Memory leaks may occur

 File locks may remain

 Unwritten data may not be saved correctly

✔ Manual Closing

f = open("[Link]")

# work

[Link]()
✔ Better Way — Using with

The best practice is to use with because it automatically closes the file even
if an exception occurs.

🔷 Reading Files Using with open()


✔ Example:

with open("[Link]", "r") as file:

content = [Link]()

print(content)

No need for [Link]().


This is safer, cleaner, and highly recommended.

🔷 Connecting to the Next Part


Now that we understand how to read files using multiple techniques, the
next step is learning how to write and create files, because reading and
writing go hand in hand.

Working with files includes:

 Creating new files

 Writing data into files

 Updating existing files

 Appending logs

These operations are crucial for real applications such as report generation,
saving records, logging activities, etc.

🔷 Writing and Creating Files in Python


After learning how to read information from files, the next essential part of
file handling is writing data to files. Writing allows programs to store
results permanently, create reports, maintain logs, save user input, and
generate documents dynamically.
Writing files is fundamental for:

 Saving user data

 Creating configuration files

 Logging activity

 Exporting results (reports, summaries)

 Creating backups

 Storing application output

Python provides flexible tools for writing in different modes depending on


your exact requirement.

🔹 Modes for Writing Files


To write data into a file, Python uses the following major modes:

Mod Function
e

"w" Write – creates new file or overwrites


existing file

"a" Append – adds data to end of file

"x" Create – creates new file and gives error if


file exists

"w+ Write + Read – overwrites file, then allows


" reading

Let’s explore each one in detail.

🔷 1. Writing to a File (write mode "w")


This mode is used to write data to a file.
If the file does not exist → Python creates it.
If the file exists → Python overwrites it.

✔ Example

file = open("[Link]", "w")


[Link]("Hello, this is a new file.\n")

[Link]("Writing data using Python.\n")

[Link]()

What happens?

 A new file [Link] is created (if not present)

 The content is written into it

 Any existing data is erased

If you run the same code again:

 The previous content disappears

 Only the new written content remains

This is why "w" mode must be used carefully.

🔹 Understanding Overwriting Effect

🔷 2. Appending to a File (append mode "a")


Append mode is used when you want to add new data to the end of an
existing file without deleting the old data.

This is ideal for:

 Log files

 Chat messages

 Activity tracking

 Continuous data writing

✔ Example

file = open("[Link]", "a")

[Link]("This line is added at the end.\n")

[Link]()

Result:
The existing file remains intact, and the new line is added at the bottom.

🔷 3. Creating a New File Safely ("x" mode)


The "x" mode creates a new file only if it does not exist.
If the file already exists, Python raises an exception to protect the original
data.

✔ Example

try:

file = open("[Link]", "x")

[Link]("Report initialized.")

[Link]()

except FileExistsError:

print("File already exists. Creation aborted.")

Why use "x"?

 Prevents accidental overwriting

 Ensures safe file creation in critical systems

🔷 4. Writing Text Using with open() (Best Practice)


Instead of manually closing files, Python recommends using with open()
because it automatically closes the file even if an error occurs.

✔ Example

with open("[Link]", "w") as file:

[Link]("This file is written using with-statement.\n")

This ensures:

 No file leaks

 Cleaner code

 Better error protection


🔷 5. Writing Multiple Lines to a File
Sometimes multiple lines need to be written at once.
We can use .writelines() for this.

✔ Example:

lines = [

"Line 1\n",

"Line 2\n",

"Line 3\n"

with open("[Link]", "w") as f:

[Link](lines)

🔷 6. Example: Saving User Input to a File


A common real-world scenario is saving user input.

✔ Example:

with open("[Link]", "a") as f:

name = input("Enter your name: ")

[Link](name + "\n")

This creates a growing list of user entries.

🔷 7. Example: Logging Application Events


Logs help track program activity.

✔ Example:

import datetime
with open("[Link]", "a") as log:

[Link](f"Program started at {[Link]()}\n")

Every time the program runs, a new log entry is added.

🔷 8. Writing Binary Files (using "wb")


Binary mode is used for non-text files like:

 Images

 Audio

 Videos

 Executables

✔ Example: Copying an Image

with open("[Link]", "rb") as src:

content = [Link]()

with open("[Link]", "wb") as dest:

[Link](content)

Binary file handling is used in:

 Image processing

 Download managers

 File manipulators

🔷 Connection to Next Topic


Now that you understand:

 How to write files

 How to append data safely


 How to create files

 How to work with text and binary data

 The importance of using with open()

The next essential part of file handling is understanding Directory


Management and the OS Module.

File handling alone is not enough; real-world programs also need to:

 Create folders

 Navigate directories

 Rename files

 Remove files

 Check if paths exist

And this is where the OS Module comes in.

🔷 OS Module and Directory Management in Python


After learning how to read and write files, the natural next step is to
understand how Python works with directories (folders) and the overall file
system. In real-world applications, you rarely work with a single file — you
deal with entire structures of folders, subfolders, and files.

Python provides the OS Module, which allows your program to interact with
the operating system in a platform-independent way.
This means your code will work on:

 Windows

 Linux

 macOS

…without needing separate instructions for each system.

The OS module is essential for:

 Creating folders

 Navigating directories

 Renaming files
 Checking file paths

 Removing files and directories

 Listing directory contents

 Building file-management applications

🔹 Introduction to the OS Module


The os module stands for Operating System, and it provides functions to
interact with the file system and manage directories.

✔ Importing the module:

import os

Once imported, you can use all built-in functions inside os.

🔷 Getting the Current Working Directory


The current working directory (CWD) is the folder where your Python
program is operating.

✔ Example:

import os

print([Link]())

Output (example):

C:\Users\Sameer\Documents

This helps you understand where your file operations are happening by
default.

🔷 Changing the Working Directory


You can move your program into another folder.

✔ Example:
[Link]("C:/Users/Sameer/Desktop")

Now Python will read/write files in that location.

Why is this useful?

 Organizing file-based programs

 Running scripts inside specific folders

 Accessing large datasets from specialized directories

🔷 Listing Files and Folders


To see everything inside a directory, use:

✔ Example:

files = [Link]()

print(files)

Output (example):

['[Link]', 'images', '[Link]']

This is useful for:

 File exploration

 Batch processing

 Automatic file scanning

 Organizing documents

🔷 Creating a Directory
Python can create new folders using [Link]().

✔ Example:

[Link]("new_folder")

Creates a folder named new_folder in the current directory.

Common uses:
 Making folders for user uploads

 Generating project directories

 Organizing log files

 Storing processed results

🔷 Creating Nested Directories


To create a chain of folders:

✔ Example:

[Link]("project/data/files")

This creates:

project/

data/

files/

Useful for full project initialization.

🔷 Removing Directories
✔ Removing an empty folder:

[Link]("new_folder")

✔ Removing nested directories:

[Link]("project/data/files")

Note:

These functions only work if the directory is empty.


To remove non-empty directories, you must use shutil module — but we
focus now on os.

🔷 Checking Whether a File or Directory Exists


Before performing operations, always check existence using [Link]().
✔ Example:

if [Link]("[Link]"):

print("File exists.")

else:

print("File not found.")

This prevents runtime errors like FileNotFoundError.

🔷 Checking Path Type (File or Directory)


✔ Example:

print([Link]("[Link]"))

print([Link]("project"))

This is useful for building file browsers.

🔷 Getting the Absolute Path


You can get the full absolute path of a file.

✔ Example:

path = [Link]("[Link]")

print(path)

This helps when:

 Sharing file paths across modules

 Debugging

 Logging

 Generating reports

🔷 Renaming Files and Folders


✔ Renaming a file:
[Link]("[Link]", "[Link]")

✔ Renaming a folder:

[Link]("old_folder", "new_folder")

Renaming is used in:

 File organization

 Versioning

 Data cleaning

 Automated workflows

🔷 Deleting Files
✔ Example:

[Link]("file_to_delete.txt")

Always combine with existence check:

if [Link]("file_to_delete.txt"):

[Link]("file_to_delete.txt")

This avoids errors.

🔷 Using OS Module in Real-World Scenarios


✔ 1. Organizing Downloads Folder

Automatically move all .mp3 files to a music folder.

✔ 2. Data Processing Pipelines

Create folders for input, output, logs, and temporary files.

✔ 3. File Backup Systems

Copy or rename files based on time or version.

✔ 4. Automated Report Generation

Store reports in separate date-based folders.


The os module allows Python to interact with the entire filesystem reliably
and efficiently.

🔷 Connecting to Next Topic


Now that we have covered:

 Directory navigation

 File & folder creation

 Checking paths

 Renaming and deleting files

 Working safely with file systems

…it’s time to learn a more modern and Pythonic way of handling paths:

👉 pathlib Module

The pathlib module makes file and directory management easier, cleaner,
and object-oriented.

🔹 Why pathlib Is Better Than OS. path?


✔ 1. Object-Oriented

Using objects allows natural expressions like:

[Link]

[Link]()

path.is_file()

instead of calling multiple separate functions.

✔ 2. Cleaner Syntax

Instead of:

[Link]("folder", "[Link]")

You can write:


Path("folder") / "[Link]"

✔ 3. Cross-Platform

Pathlib automatically handles:

 Windows paths → C:\Users\Sameer\Documents

 Linux paths → /home/sameer/documents

 Mac paths → /Users/sameer/Documents

No extra effort needed.

✔ 4. Integrated File Operations

Pathlib objects can:

 Read files

 Write files

 Iterate through directories

 Check attributes

without importing multiple modules.

🔷 Importing the pathlib Module


✔ Example:

from pathlib import Path

Once imported, you can create Path objects.

🔷 Creating Path Objects


Path objects represent file or directory paths.

✔ Example:

p = Path("[Link]")

print(p)

This does not create a file — it just represents the path.


🔷 Checking Whether a File or Directory Exists
✔ Example:

p = Path("[Link]")

print([Link]())

This returns:

 True → if file or directory exists

 False → if not

🔷 Checking Path Type


✔ Check if path is a file:

p = Path("[Link]")

print(p.is_file())

✔ Check if path is a directory:

d = Path("documents")

print(d.is_dir())

🔷 Reading Text Files with pathlib


Pathlib provides an easier way to read text.

✔ Example:

p = Path("[Link]")

content = p.read_text()

print(content)

This automatically:

 Opens file

 Reads file
 Closes file

No manual handling required.

🔷 Writing Text Files with pathlib


Use .write_text() to quickly write content.

✔ Example:

p = Path("[Link]")

p.write_text("Hello from pathlib!")

If file does not exist → it is created


If file exists → it is overwritten

🔷 Appending to Files with pathlib


Pathlib does not have .append_text(),
so we combine the read–modify–write approach.

✔ Example:

p = Path("[Link]")

old = p.read_text()

p.write_text(old + "\nNew line added.")

Useful for logs, history, notes, etc.

🔷 Working with Binary Files


✔ Example:

p = Path("[Link]")

data = p.read_bytes()

q = Path("[Link]")

q.write_bytes(data)
Binary file processing is important for:

 Images

 PDFs

 Videos

 ZIP files

🔷 Creating Directories using pathlib


✔ Create a single folder:

Path("myfolder").mkdir()

✔ Create nested directories:

Path("projects/data/files").mkdir(parents=True)

This is equivalent to [Link]().

🔷 Iterating Through Directory Contents


Pathlib makes directory traversal easy and elegant.

✔ Example:

p = Path(".") # current directory

for item in [Link]():

print(item)

You can filter:

✔ Only files:

for file in [Link]():

if file.is_file():

print(file)

✔ Only directories:
for d in [Link]():

if d.is_dir():

print(d)

🔷 Joining Paths Using the / Operator


This is one of pathlib’s best features.

✔ Example:

folder = Path("projects")

file_path = folder / "[Link]"

print(file_path)

This results in:

projects/[Link]

This is clearer and safer than string concatenation.

🔷 Renaming and Deleting Files Using pathlib


✔ Rename:

p = Path("[Link]")

[Link]("[Link]")

✔ Delete:

p = Path("delete_me.txt")

[Link]()

Equivalent to [Link]().

🔷 Combining pathlib with Exception Handling


Since file operations can fail, pathlib works perfectly with try–except.

✔ Example:
from pathlib import Path

p = Path("[Link]")

try:

data = p.read_text()

print(data)

except FileNotFoundError:

print("The file does not exist.")

This creates powerful and stable scripts.

🔷 Real-World Use Cases of pathlib


✔ 1. Application folder setup

Creating new directories for logs, configs, backups.

✔ 2. Data science pipelines

Navigating datasets and processing CSV files.

✔ 3. File organization systems

Sorting images, documents, audio files.

✔ 4. Package development

Handling internal file structures.

✔ 5. Working with cross-platform paths

Ensures your script works on all operating systems.

🔷 Connecting to Next Topic


We now understand:
 How to work with files using open()

 How to manage directories using os

 How to work with paths using pathlib

The final part of your required topic is a broader category that ties
everything together:

👉 Directory Management (Full Overview)

This section covers combining file handling, os module, and pathlib module
to professionally manage directories and files.

🔷 Directory Management in Python

Directory management refers to controlling and manipulating folders within


your operating system using Python. This includes tasks such as creating
folders, navigating between directories, renaming them, deleting them,
scanning their contents, and organizing files programmatically.

Directory management is essential because real-world software and scripts


often need to:

 Organize files

 Separate input and output data

 Create backups and logs

 Process thousands of files

 Manage structured project folders

 Clean unnecessary files

 Build automation pipelines

Python provides multiple tools for directory management, especially through:

 The os module

 The pathlib module

Both can achieve the same goals, but pathlib offers a modern approach.

🔹 Understanding Directories in File Systems


A directory (folder) is a container that stores files and other subdirectories.
Directories form a tree-like structure:

Python can navigate and manipulate any part of this structure.

🔷 Getting the Current Working Directory

The current working directory (CWD) is where Python starts its operations.

✔ Using os:

import os

print([Link]())

✔ Using pathlib:

from pathlib import Path

print([Link]())

🔷 Changing the Working Directory

You can switch to another directory.

✔ Using os:

[Link]("C:/Users/Sameer/Desktop")

✔ Using pathlib:
path = Path("C:/Users/Sameer/Desktop")

[Link](path)

Changing directories is necessary when your program deals with files located
in different places.

🔷 Listing Directory Contents

To see what files and folders exist inside a directory:

✔ Using os:

print([Link]())

✔ Using pathlib:

for item in Path(".").iterdir():

print(item)

Pathlib’s output is more structured because each element is a Path object.

🔷 Creating Directories

✔ Creating a single folder (os):

[Link]("new_folder")

✔ Creating nested folders (os):

[Link]("projects/data/logs")

✔ Creating folder with pathlib:

Path("new_folder").mkdir()

✔ Creating nested folders with pathlib:

Path("projects/data/logs").mkdir(parents=True)

🔷 Removing Directories

Directories must be empty to remove them using os.

✔ Using os:
[Link]("empty_folder")

✔ Removing nested empty directories:

[Link]("projects/data/logs")

✔ Using pathlib:

Path("empty_folder").rmdir()

Important:
To delete non-empty directories, you need the shutil module:

import shutil

[Link]("folder_name")

This deletes everything inside the folder.

🔷 Checking Existence of Directories


Before performing operations, always confirm whether the directory exists.

✔ Using os:

if [Link]("myfolder"):

print("Folder exists.")

✔ Using pathlib:

p = Path("myfolder")

print([Link]())

🔷 Checking Whether Path Is File or Directory


✔ os:

[Link]("myfolder")

[Link]("[Link]")

✔ pathlib:

p = Path("[Link]")

print(p.is_file())
print(p.is_dir())

🔷 Renaming Directories
✔ Using os:

[Link]("old_folder", "new_folder")

✔ Using pathlib:

Path("old_folder").rename("new_folder")

Useful when organizing project structure.

🔷 Moving Files Between Directories


The shutil module is used for moving.

✔ Example:

import shutil

[Link]("[Link]", "backup/")

This is crucial for automated sorting systems.

🔷 Iterating Through Files in a Directory


✔ Using pathlib:

p = Path("documents")

for file in [Link]():

if file.is_file():

print("File:", file)

✔ Filtering by file type:

for file in [Link]("*.txt"):

print(file)
This is extremely useful for batch-processing text files, CSVs, logs, etc.

🔷 Recursively Searching Directories


✔ Using pathlib:

for file in Path(".").rglob("*.py"):

print(file)

This scans all subdirectories too.

🔷 Creating a Directory Structure Programmatically


A common real-world example is initializing a project folder.

✔ Example:

from pathlib import Path

root = Path("project")

(root / "input").mkdir(parents=True, exist_ok=True)

(root / "output").mkdir(exist_ok=True)

(root / "logs").mkdir(exist_ok=True)

print("Project structure created.")

This creates:

project/

input/

output/

logs/
🔷 Directory Management: Combined Example
Below is a complete example combining reading, writing, directory creation,
and path checking.

✔ Example:

from pathlib import Path

project = Path("my_app")

(project / "data").mkdir(parents=True, exist_ok=True)

file_path = project / "data" / "[Link]"

# Write file

file_path.write_text("User1\nUser2\n")

# Read file

print("File content:")

print(file_path.read_text())

# List directory

print("Files in /data:")

for f in (project / "data").iterdir():

print(f)

This example shows how simple directory management becomes with


pathlib.

🔷 Directory Management in Real-World Applications


Directory management is essential in:
✔ Data Analytics

Organizing raw data, processed data, results, visualizations.

✔ Web Applications

Managing uploaded files, logs, media files, configuration.

✔ Automation Scripts

Sorting files automatically, creating backups, cleaning folders.

✔ Machine Learning

Separating training, validation, and test datasets.

✔ System Tools

Writing scripts to monitor file systems or generate reports.

🔷 Final Connection
You now understand:

 Exception Handling

 Built-in Exceptions

 User-defined Exceptions

 File Reading

 File Writing

 OS Module

 Pathlib Module

 Directory Management

Together, these topics form the backbone of real-world file and error-handling
tasks in Python.

You might also like