Learn
🤖 AI Hub 📰 News 📖 Dictionary 🧰 Resources
Grow
💼 Jobs 🚀 Community 🏆 Challenges
Explore by Stage
🌑 Zero 📚 Learn 🔧 Practice 🏗 Build 🚀 Launch 💰 Earn
Account
Login Sign Up
🏗️HTML 🎨CSS ⚡JavaScript 🐙Git & GitHub ⚛️React Soon 📘TypeScript Soon 🐍Python 🗄️Database & SQL Soon 🌐Web Development Soon ☁️Cloud & DevOps Soon 🤖AI & ML Soon 📄Resume Prep Soon 🎤Interview Prep Soon 💼Freelancing Soon 🚀SaaS & Side Projects Soon 🤖Automation Soon
Intermediate 🕑 11 min read 👁 1 views 📅 Oct 22, 2026

Working with Files: Reading and Writing Text

Read and write text files in Python with open() and with blocks, choose the right mode (r, w, a), loop over lines, handle Hindi text with UTF-8, keep a log and use pathlib.

Why This Matters: The Mess Notebook

In a college hostel in Pune, the mess manager keeps a notebook. Every morning he writes who came for breakfast. At the end of the month, he reads the notebook to count plates and plan rations. The notebook is useful because it remembers. Close it today, open it next week, and the writing is still there.

Python variables do not remember anything. When your program ends, every list and dictionary disappears. To keep data for later, a program must write it to a file, and read it back the next time it runs.

In this lesson you will open files in different modes, write and read text, loop over lines, handle Hindi text with the right encoding, keep a log, count words, use pathlib, and deal with a file that does not exist.

About the playground: every Try it yourself run starts in a fresh, empty folder, so each example below first creates the file it reads. On your own computer, files stay in the folder where you run your program, and you can open them in VS Code.

open() and the with Block

The built-in open() function connects your program to a file. It takes the file name and a mode that says what you want to do. The safest way to use it is inside a with block:

# Step 1: write. "w" creates the file (or empties it if it already exists)
with open("attendance.txt", "w", encoding="utf-8") as file:
    file.write("Rahul\n")
    file.write("Sneha\n")
    file.write("Arif\n")

# Step 2: read. "r" opens the file for reading
with open("attendance.txt", "r", encoding="utf-8") as file:
    text = file.read()

print(text)
# Rahul
# Sneha
# Arif

The with block opens the file, gives it to you as file, and closes it automatically when the indented block ends, even if an error happens. A closed file is saved properly and released for other programs. Without with, you must remember to call file.close() yourself, and it is easy to forget.

Notice the \n at the end of each name. write() writes exactly the text you give it and nothing more. \n is the new line character, which ends the line.

The Three Main Modes: r, w and a

ModeMeaningIf the file does not existIf the file exists
"r"Read (the default)FileNotFoundErrorReads from the start
"w"WriteCreates itErases everything, then writes
"a"AppendCreates itKeeps the old text and adds at the end

The difference between "w" and "a" is the most important thing to remember in this lesson. Watch what happens to Monday's menu:

# "w" writes a fresh file
with open("menu.txt", "w", encoding="utf-8") as file:
    file.write("Monday: Poha\n")

# "w" again: the old content is ERASED first
with open("menu.txt", "w", encoding="utf-8") as file:
    file.write("Tuesday: Upma\n")

# "a" appends: new text goes at the end, old text stays
with open("menu.txt", "a", encoding="utf-8") as file:
    file.write("Wednesday: Idli Sambar\n")
    file.write("Thursday: Aloo Paratha\n")

with open("menu.txt", encoding="utf-8") as file:    # "r" is the default mode
    print(file.read())
# Tuesday: Upma
# Wednesday: Idli Sambar
# Thursday: Aloo Paratha
# (Monday is gone: the second "w" erased it)

Writing Many Lines and Reading in Different Ways

writelines() writes every string from a list. It does not add new lines for you, so each string needs its own \n. For reading, you have three methods:

  • read() gives the whole file as one string.
  • readline() gives the next single line each time you call it.
  • readlines() gives a list with one string per line.
students = ["Rahul\n", "Sneha\n", "Arif\n", "Divya\n"]

with open("attendance.txt", "w", encoding="utf-8") as file:
    file.writelines(students)       # writes every string in the list

# readline(): one line at a time
with open("attendance.txt", encoding="utf-8") as file:
    first = file.readline()
    second = file.readline()
print(repr(first), repr(second))     # 'Rahul\n' 'Sneha\n'

# readlines(): all lines as a list
with open("attendance.txt", encoding="utf-8") as file:
    lines = file.readlines()
print(lines)          # ['Rahul\n', 'Sneha\n', 'Arif\n', 'Divya\n']
print(len(lines), "students")        # 4 students

repr() shows a string with its hidden characters, so you can see the \n that is really there at the end of each line.

Looping Over Lines and Using strip()

The most common way to read a file is a for loop directly over the file. It gives you one line per loop and never loads the whole file into memory, so it works even for very big files. Each line still ends with \n, so call strip() to remove it (and any extra spaces) before you use the line.

# Create the file first (each run starts with an empty folder)
with open("breakfast.txt", "w", encoding="utf-8") as file:
    file.write("Rahul,present\n")
    file.write("Sneha,absent\n")
    file.write("Arif,present\n")
    file.write("Divya,present\n")

present = 0
with open("breakfast.txt", encoding="utf-8") as file:
    for line in file:                    # one line per loop, memory-friendly
        line = line.strip()              # remove the "\n" at the end
        name, status = line.split(",")
        print(f"{name:<6} {status}")
        if status == "present":
            present += 1

print("Breakfast plates needed:", present)    # Breakfast plates needed: 3

Here each line holds two values separated by a comma, and split(",") breaks it into a name and a status. This simple idea is the start of the CSV format, which you will meet in the JSON and CSV lesson.

encoding="utf-8": Hindi and Other Languages

A computer stores text as numbers. An encoding is the rule that turns characters into those numbers. UTF-8 is the modern standard. It can store every script, including Hindi, Tamil, Bengali and emoji. The hostel's Hindi menu works perfectly with it:

hindi_menu = [
    "सोमवार: पोहा और चाय\n",
    "मंगलवार: उपमा और केला\n",
    "बुधवार: इडली सांभर\n",
]

with open("menu_hindi.txt", "w", encoding="utf-8") as file:
    file.writelines(hindi_menu)

with open("menu_hindi.txt", encoding="utf-8") as file:
    for line in file:
        print(line.strip())
# सोमवार: पोहा और चाय
# मंगलवार: उपमा और केला
# बुधवार: इडली सांभर
Make it a habit: always write encoding="utf-8" when you open a text file. Without it, Python uses your computer's default, which on some Windows computers is not UTF-8. A file with Hindi, Tamil or even the Rs symbol can then fail to save or show strange characters.

Counting Words in a File

Once the text is in a string, all your string skills work. split() with no argument splits on any spaces and new lines, so len(text.split()) counts the words. A dictionary can count how often each word appears.

notice = """Dear students, the mess will serve a special dinner on Saturday.
Please mark your attendance by Friday evening.
Students who do not mark attendance will not get a coupon."""

with open("notice.txt", "w", encoding="utf-8") as file:
    file.write(notice)

with open("notice.txt", encoding="utf-8") as file:
    text = file.read()

lines = text.splitlines()
words = text.split()          # split() with no argument splits on any spaces or new lines
print("Lines:", len(lines))   # Lines: 3
print("Words:", len(words))   # Words: 29

# How many times does each word appear? (lower case, without full stops and commas)
counts = {}
for word in words:
    word = word.lower().strip(".,")
    counts[word] = counts.get(word, 0) + 1
print("'attendance' appears", counts["attendance"], "times")   # 2 times

pathlib: A Modern Way to Work With Files

The pathlib module from the standard library gives you a Path object for a file name. It has useful methods: exists() checks whether the file is there, and read_text() and write_text() read or write a whole file in one line, opening and closing it for you.

from pathlib import Path

notes = Path("mess_notes.txt")
print(notes.exists())              # False: nothing written yet

notes.write_text("Gas cylinder changed\nNew cook joins on Monday\n", encoding="utf-8")
print(notes.exists())              # True

text = notes.read_text(encoding="utf-8")
print(text.splitlines())           # ['Gas cylinder changed', 'New cook joins on Monday']

print(notes.name)                  # mess_notes.txt
print(notes.suffix)                # .txt
print(notes.stem)                  # mess_notes

Use read_text() and write_text() for small files. For adding lines one by one, or reading a big file line by line, open() with with is still the right tool, and it accepts a Path too.

Real-Life Example: The Mess Meal Log

Now the manager's notebook becomes a program. record_meal() appends one line for each meal, so the log grows day by day and nothing is lost. daily_summary() reads the log and adds up the plates for each day. The first summary runs before any meal is recorded, to show that the program handles a missing file politely.

from pathlib import Path

LOG = Path("mess_log.txt")

def record_meal(day, meal, students):
    """Add one line to the log. 'a' keeps all the earlier lines."""
    with open(LOG, "a", encoding="utf-8") as file:
        file.write(f"{day},{meal},{students}\n")

def daily_summary():
    if not LOG.exists():
        print("No meals recorded yet.")
        return

    totals = {}
    with open(LOG, encoding="utf-8") as file:
        for line in file:
            line = line.strip()
            if not line:                  # skip empty lines
                continue
            day, meal, students = line.split(",")
            totals[day] = totals.get(day, 0) + int(students)

    for day, plates in totals.items():
        print(f"{day:<10} {plates:>4} plates")
    print(f"{'Total':<10} {sum(totals.values()):>4} plates")

daily_summary()                       # nothing yet

record_meal("Monday", "Breakfast", 112)
record_meal("Monday", "Lunch", 130)
record_meal("Monday", "Dinner", 125)
record_meal("Tuesday", "Breakfast", 108)
record_meal("Tuesday", "Lunch", 134)

daily_summary()
print()
print("Raw file:")
print(LOG.read_text(encoding="utf-8"))

Try these changes:

  1. Record Tuesday's dinner and run it again.
  2. Change the summary to show the total for each meal (Breakfast, Lunch, Dinner) instead of each day.
  3. Change "a" to "w" in record_meal() and see what is left in the log. Then change it back!

Common Mistakes

  • Reading a file that does not exist. Mode "r" never creates a file, so Python stops with an error:
with open("feedback.txt", encoding="utf-8") as file:    # ERROR: FileNotFoundError
    print(file.read())

Fix: check first with Path.exists(), as below. In the Error Handling lesson you will also learn to catch this error with try and except.

from pathlib import Path

feedback = Path("feedback.txt")

if feedback.exists():
    print(feedback.read_text(encoding="utf-8"))
else:
    print("No feedback yet. Creating an empty file.")
    feedback.write_text("", encoding="utf-8")
  • Using "w" when you meant "a". One wrong letter erases a month of records. Fix: use "a" to add to a log, and "w" only when you want to replace the whole file.
  • Forgetting \n. write("Rahul") followed by write("Sneha") gives RahulSneha on one line. Fix: end each line with \n.
  • Forgetting strip(). "present\n" == "present" is False, so your counts come out as zero. Fix: strip every line you read.
  • Leaving out the encoding. The code may work on your laptop and fail on a friend's. Fix: always pass encoding="utf-8".

Practice Task: Mess Feedback File

The hostel collects one feedback line per day in the form day,rating,comment. Complete the TODO steps:

  • Write the first three days with writelines().
  • Append two more days without losing the first three.
  • Read the file line by line and count the good and bad days.
  • Count all the words in the comments.
  • Check with Path that the file exists.
from pathlib import Path

first_week = [
    "Monday,good,The poha was hot and fresh\n",
    "Tuesday,bad,Upma was too salty\n",
    "Wednesday,good,Loved the idli\n",
]

# TODO 1: write first_week into "feedback.txt" with writelines()
# TODO 2: append two more lines: Thursday (good) and Friday (bad),
#         each with a short comment
# TODO 3: read the file line by line, strip each line, and count
#         how many days were "good" and how many were "bad"
# TODO 4: print the total number of words in all the comments
# TODO 5: use Path to print whether "feedback.txt" exists
Show one possible answer (try it yourself first!)
from pathlib import Path

first_week = [
    "Monday,good,The poha was hot and fresh\n",
    "Tuesday,bad,Upma was too salty\n",
    "Wednesday,good,Loved the idli\n",
]

with open("feedback.txt", "w", encoding="utf-8") as file:
    file.writelines(first_week)

with open("feedback.txt", "a", encoding="utf-8") as file:
    file.write("Thursday,good,Parathas with curd\n")
    file.write("Friday,bad,Dinner was served late\n")

good = 0
bad = 0
comment_words = 0
with open("feedback.txt", encoding="utf-8") as file:
    for line in file:
        day, rating, comment = line.strip().split(",")
        if rating == "good":
            good += 1
        else:
            bad += 1
        comment_words += len(comment.split())

print("Good days:", good)              # Good days: 3
print("Bad days:", bad)                # Bad days: 2
print("Words in comments:", comment_words)   # Words in comments: 20
print("File exists:", Path("feedback.txt").exists())   # File exists: True

Key Takeaways

  • Files let your program remember data after it ends. Open them with open() inside a with block, which closes them for you.
  • "r" reads, "w" erases and writes, "a" adds to the end. Choose carefully.
  • write() and writelines() do not add new lines: put \n yourself. Use strip() when you read lines.
  • Loop directly over a file to read it line by line, and always pass encoding="utf-8".
  • pathlib.Path gives you exists(), read_text() and write_text(). Reading a missing file raises FileNotFoundError.

❓ Frequently Asked Questions

In the current working folder, which is usually the folder where you ran the program. In VS Code, open the project folder and run the program from its terminal, and the file will appear in the Explorer.
No. The with block closes the file automatically when the block ends, even if an error happens inside it.
Python has modes such as "r+" for that, but they are easy to get wrong. For beginners it is much safer to read the file, close it, and then open it again to write.
write() accepts only strings, so convert numbers first, for example file.write(f"{plates}\n"). When you read them back, use int() or float() to turn the text into a number again.
Was this lesson helpful?

🎯 Finished this lesson?

🔗 Related Tutorials
🤖 Got a Doubt? Ask AI
Get instant answers in Hindi or English
🤖
Z2T Bot
Online
Ask me anything about this tutorial — I'm here! 👋