BASIC Python (Beginner Level) 📂 Basic Python Programming · 14 of 15 180 min read

Python File Handling

Master reading and writing text files in Python: how open() works, every file mode (r, w, a, x, r+, w+, a+) and what each one does to your data, why with is the only safe way to open files, all four reading techniques (read, readline, readlines, iteration), writing and appending, why encoding="utf-8" is non-negotiable, pathlib basics, and the specific exceptions you must handle in real code.

🌐
SectionSection第 01 节

Why File Handling Matters — Programs That Remember 📒File Handling क्यों ज़रूरी है — याद रखने वाले Programs 📒为什么文件处理很重要 — 会记忆的程序 📒

The Notebook on Your Deskआपकी मेज़ पर रखी नोटबुक你桌上的笔记本
Imagine arriving at your desk every morning with total amnesia. Yesterday's notes, meeting results, phone numbers — all gone. That is exactly how a program behaves without files: it runs, computes brilliantly for a few seconds, then ends and takes all its memory with it.

A file is the notebook on your desk. You write things in it, close it, and tomorrow — or ten years from now — you open it and carry on where you left off. File handling is how programs turn short-term memory into long-term memory.
सोचिए कि आप हर सुबह मेज़ पर पहुँचते हैं और सब कुछ भूल चुके होते हैं। कल के notes, meeting के नतीजे, फ़ोन नंबर — सब ग़ायब। Files के बिना program ठीक ऐसा ही होता है: वह चलता है, कुछ सेकंड शानदार हिसाब करता है, फिर ख़त्म होकर अपनी सारी याददाश्त साथ ले जाता है।

File आपकी मेज़ पर रखी नोटबुक है। आप उसमें लिखते हैं, उसे बंद करते हैं, और कल — या दस साल बाद — उसे खोलकर वहीं से शुरू करते हैं जहाँ छोड़ा था। File handling ही वह तरीका है जिससे programs अपनी थोड़ी देर की याद को लंबी याद में बदलते हैं।
想象你每天早上来到办公桌前,都完全失忆了。昨天的笔记、会议结果、电话号码 — 全都没了。没有文件的程序正是这样:它运行几秒、出色地完成计算,然后结束,把所有记忆一并带走。

文件 就是你桌上的那本笔记本。你在里面写东西,合上它,明天 — 甚至十年后 — 再打开它,从上次停下的地方继续。文件处理就是程序把短期记忆变成长期记忆的方法。

In Python, a text file is a sequence of characters stored on disk. Files come in two kinds — text (readable characters: source code, CSV, logs, JSON, HTML) and binary (images, executables, PDFs). This tutorial focuses on text files, which cover most everyday scripting.

Python में text file disk पर रखे अक्षरों का एक क्रम है। Files दो तरह की होती हैं — text (पढ़े जा सकने वाले अक्षर: source code, CSV, logs, JSON, HTML) और binary (images, executables, PDFs)। यह tutorial text files पर केंद्रित है, जो रोज़ के ज़्यादातर scripting काम में आती हैं।

在 Python 中,文本文件 是存储在磁盘上的一串字符。文件分两类 — 文本(可读字符:源代码、CSV、日志、JSON、HTML)和 二进制(图片、可执行文件、PDF)。本教程专注于文本文件,它们覆盖了日常脚本中的大部分需求。

Every File Job Has Three Stepsहर File काम के तीन कदम每个文件操作都有三步
open, read or write, closewith open(...) as f: ← closes for youwith open(...) as f: ← आपके लिए बंद करता हैwith open(...) as f: ← 自动帮你关闭open()get a file objectfile object पाएँ得到文件对象read() / write()move datadata लाएँ-ले जाएँ传送数据close()flush + releaseflush + छोड़ें刷新 + 释放💾 notes.txt

Open the file, move data in or out, then close it. The with statement (dashed box) does the closing for you.

File खोलें, data अंदर या बाहर ले जाएँ, फिर उसे बंद करें। with statement (बिंदीदार डिब्बा) बंद करने का काम आपके लिए करता है।

打开文件,读入或写出数据,然后关闭它。with 语句(虚线框)会替你完成关闭。

📚
The Core Insightमूल बात核心要点

Reading and writing files always follows the same three-step ritual: open the file, read or write the data, then close it. Skip the last step and your writes may not reach the disk, the file can stay locked, and other programs may see empty output. Python's with statement handles this ritual for you — use it almost every time.

Files पढ़ना और लिखना हमेशा एक ही तीन-कदम की रीत से होता है: file खोलें, data पढ़ें या लिखें, फिर उसे बंद करें। आख़िरी कदम छोड़ें तो आपके writes शायद disk तक न पहुँचें, file locked रह सकती है, और दूसरे programs को ख़ाली output दिख सकता है। Python का with statement यह रीत आपके लिए निभाता है — लगभग हर बार इसे इस्तेमाल करें।

读写文件总是遵循同样的三步仪式:打开 文件,读或写 数据,然后 关闭 它。漏掉最后一步,你写的内容可能到不了磁盘,文件可能一直被锁住,其他程序可能看到空的输出。Python 的 with 语句会替你完成这个仪式 — 几乎每次都应该使用它。

▶️
This Tutorial Has Five Simulators and a Quizइस Tutorial में पाँच Simulators और एक Quiz है本教程有五个模拟器和一个小测验

Look for the interactive boxes: the Mode Explorer (Section 03), the Buffer Visualizer (04), the Read Cursor Lab (05), the Encoding Lab (08) and the Path Explorer (09). They follow real Python rules — every result and error was checked against Python itself.

Interactive डिब्बे खोजें: Mode Explorer (Section 03), Buffer Visualizer (04), Read Cursor Lab (05), Encoding Lab (08) और Path Explorer (09)। ये असली Python के नियमों पर चलते हैं — हर result और error को ख़ुद Python से मिलाकर जाँचा गया है।

请留意这些互动框:Mode Explorer(第 03 节)、Buffer Visualizer(04)、Read Cursor Lab(05)、Encoding Lab(08)和 Path Explorer(09)。它们遵循真实的 Python 规则 — 每个结果和错误都与 Python 本身核对过。


SectionSection第 02 节

The open() Function — Your Gateway to Every File 🚪open() Function — हर File का दरवाज़ा 🚪open() 函数 — 通往每个文件的大门 🚪

Every file job starts with the built-in open() function. It takes a path and a mode, and gives back a file object you can read from or write to.

हर file का काम built-in open() function से शुरू होता है। यह एक path और एक mode लेता है, और एक file object लौटाता है जिससे आप पढ़ या लिख सकते हैं।

每个文件操作都从内置函数 open() 开始。它接收一个路径和一个模式,返回一个可以读写的 文件对象。

# Basic syntax (we will improve it in Section 04)
f = open("notes.txt", "r", encoding="utf-8")
content = f.read()
f.close()
print(content)
OUTPUT
Buy milk Finish tutorial Call mom
🛠️ Anatomy of open()open() की बनावटopen() 的结构
path
Where the file is — a relative name like notes.txt or a full path like /var/log/app.log. Can be a string or a pathlib.Path. File कहाँ है — notes.txt जैसा relative नाम या /var/log/app.log जैसा पूरा path। String या pathlib.Path हो सकता है। 文件在哪里 — 像 notes.txt 这样的相对名字,或像 /var/log/app.log 这样的完整路径。可以是字符串或 pathlib.Path。
mode
What you want to do — read, write or append. Full table in Section 03. The default is "r" (read text). आप क्या करना चाहते हैं — पढ़ना, लिखना या जोड़ना। पूरी table Section 03 में। Default "r" है (text पढ़ना)। 你想做什么 — 读、写或追加。完整表格见第 03 节。默认是 "r"(读文本)。
encoding
How bytes become characters. Use "utf-8". Section 08 explains why. Bytes अक्षरों में कैसे बदलें। "utf-8" इस्तेमाल करें। क्यों, यह Section 08 बताता है। 字节如何变成字符。请使用 "utf-8"。第 08 节解释原因。
newline
How line endings are handled. Leave it alone for text: when reading, Python turns \r\n and \r into \n; when writing, \n becomes the system's line ending. Line के अंत कैसे संभाले जाएँ। Text के लिए इसे न छेड़ें: पढ़ते समय Python \r\n और \r को \n बना देता है; लिखते समय \n system का line-ending बन जाता है। 如何处理行尾。处理文本时不要改它:读取时 Python 把 \r\n 和 \r 转成 \n;写入时 \n 会变成系统的行尾符。
⚠️
Always Pass encoding="utf-8"हमेशा encoding="utf-8" दें始终传入 encoding="utf-8"

Without it, Python 3.14 and older use the system's locale encoding — often cp1252 on Windows, utf-8 on Linux and macOS. Your script works on your machine and garbles names on a colleague's. Python 3.15 (released October 2026) finally makes UTF-8 the default everywhere (PEP 686), but your code may still run on older versions. Writing encoding="utf-8" works on every version and tells every reader what you meant.

इसके बिना Python 3.14 और पुराने versions system की locale encoding इस्तेमाल करते हैं — Windows पर अक्सर cp1252, Linux और macOS पर utf-8। आपका script आपकी मशीन पर चलता है और साथी की मशीन पर नाम बिगाड़ देता है। Python 3.15 (अक्टूबर 2026 में आया) आख़िरकार हर जगह UTF-8 को default बनाता है (PEP 686), पर आपका code पुराने versions पर भी चल सकता है। encoding="utf-8" लिखना हर version पर चलता है और हर पढ़ने वाले को आपका इरादा बताता है।

不写它的话,Python 3.14 及更早版本会使用系统的区域编码 — Windows 上常常是 cp1252,Linux 和 macOS 上是 utf-8。你的脚本在自己电脑上正常,在同事电脑上却把名字弄成乱码。Python 3.15(2026 年 10 月发布)终于让 UTF-8 在所有平台上成为默认(PEP 686),但你的代码可能仍会在旧版本上运行。写上 encoding="utf-8" 在每个版本上都有效,也让每位读者明白你的意图。


SectionSection第 03 节

File Modes — Read, Write, Append (and the Ones That Bite) 🎛️File Modes — पढ़ना, लिखना, जोड़ना (और जो काट लेते हैं) 🎛️文件模式 — 读、写、追加(以及会咬人的那些)🎛️

The second argument to open() is the mode. Pick the wrong one and you either can't do what you want — or worse, you silently destroy an existing file.

open() का दूसरा argument mode है। ग़लत चुनें तो या तो आप वह नहीं कर पाते जो चाहते हैं — या उससे बुरा, चुपचाप किसी मौजूदा file को नष्ट कर देते हैं।

open() 的第二个参数是 模式。选错了,要么做不了你想做的事 — 要么更糟,悄无声息地毁掉一个已有文件。

ModeMode模式Meaningअर्थ含义File must exist?File पहले से हो?文件必须存在?Wipes existing content?पुराना content मिटाता है?清空已有内容?Cursor starts atCursor कहाँ से光标起点
"r"Read onlyसिर्फ़ पढ़ना只读Yesहाँ是Noनहीं否Beginningशुरुआत开头
"w"Write onlyसिर्फ़ लिखना只写No — creates itनहीं — बना देता है否 — 会创建Yes — truncates!हाँ — ख़ाली कर देता है!是 — 截断!Beginningशुरुआत开头
"a"Append onlyसिर्फ़ जोड़ना只追加No — creates itनहीं — बना देता है否 — 会创建Noनहीं否Endअंत末尾
"x"Exclusive create (write)सिर्फ़ नई file बनाना (लिखना)独占创建(写)No — must NOT existनहीं — होनी ही नहीं चाहिए否 — 必须不存在Noनहीं否Beginningशुरुआत开头
"r+"Read + write (writes overwrite)पढ़ना + लिखना (write ऊपर लिखता है)读 + 写(写入会覆盖)Yesहाँ是Noनहीं否Beginningशुरुआत开头
"w+"Write + readलिखना + पढ़ना写 + 读No — creates itनहीं — बना देता है否 — 会创建Yes — truncates!हाँ — ख़ाली कर देता है!是 — 截断!Beginningशुरुआत开头
"a+"Append + readजोड़ना + पढ़ना追加 + 读No — creates itनहीं — बना देता है否 — 会创建Noनहीं否Endअंत末尾
🚩
The Silent Destroyer — Mode "w"चुपचाप नष्ट करने वाला — Mode "w"无声的毁灭者 — 模式 "w"

Opening an existing file in mode "w" — even to write a single character — empties the whole file at once. No confirmation, no undo, no warning. If you meant to add to a file, you wanted "a", not "w". Making this mistake on config.json has ruined many a Friday afternoon.

किसी मौजूदा file को mode "w" में खोलना — एक अक्षर लिखने के लिए भी — पूरी file को तुरंत ख़ाली कर देता है। न पुष्टि, न undo, न चेतावनी। अगर आप file में जोड़ना चाहते थे, तो आपको "a" चाहिए था, "w" नहीं। config.json पर यह ग़लती कई शुक्रवार की शामें बर्बाद कर चुकी है।

用模式 "w" 打开一个已有文件 — 哪怕只写一个字符 — 都会 立刻清空整个文件。没有确认,没有撤销,没有警告。如果你想往文件里追加,你需要的是 "a" 而不是 "w"。在 config.json 上犯这个错误,毁掉过不少人的周五下午。

Try It — Mode Explorerकरके देखें — Mode Explorer动手试试 — 模式探索器

Pick a mode, choose what notes.txt looks like before you start, and pick what to do. Watch the file on disk (each box is one character, ↵ is a newline) and the orange cursor — the place where the next read or write happens.

एक mode चुनें, चुनें कि शुरू में notes.txt कैसी है, और चुनें क्या करना है। Disk पर file देखें (हर डिब्बा एक अक्षर है, ↵ एक newline है) और नारंगी cursor — वह जगह जहाँ अगला read या write होगा।

选择一个模式,选择开始前 notes.txt 的样子,再选择要做的操作。观察磁盘上的文件(每个方框是一个字符,↵ 是换行)和橙色的 光标 — 下一次读或写发生的位置。

🎛️ Mode ExplorerSame file, seven modes — see what each one really does.एक file, सात modes — देखें हर एक असल में क्या करता है।同一个文件,七种模式 — 看看每种到底做了什么。
mode
notes.txt
doकरें操作

Text Mode vs Binary ModeText Mode बनाम Binary Mode文本模式与二进制模式

Add "b" to a mode (like "rb", "wb") and you are in binary mode: you read and write raw bytes instead of decoded strings, with no encoding and no newline changes. Use binary for images, PDFs and archives. For anything people read, stay in text mode.

Mode में "b" जोड़ें (जैसे "rb", "wb") तो आप binary mode में हैं: आप decode हुए strings की जगह कच्चे bytes पढ़ते-लिखते हैं, बिना encoding और बिना newline बदलाव के। Images, PDFs और archives के लिए binary इस्तेमाल करें। जो कुछ इंसान पढ़ते हैं, उसके लिए text mode में रहें।

在模式后加上 "b"(如 "rb"、"wb")就进入二进制模式:读写的是原始 bytes 而不是解码后的字符串,没有编码,也不转换换行。图片、PDF 和压缩包用二进制模式。凡是给人读的内容,都用文本模式。

# Binary mode: bytes in, bytes out — no encoding, no newline changes
with open("data.bin", "wb") as f:
    f.write(bytes([72, 105, 0, 255]))

with open("data.bin", "rb") as f:
    raw = f.read()

print(raw, type(raw).__name__, len(raw))
print(list(raw))
OUTPUT
b'Hi\x00\xff' bytes 4 [72, 105, 0, 255]

SectionSection第 04 节

The with Statement — The Right Way to Open Files 🛡️with Statement — Files खोलने का सही तरीका 🛡️with 语句 — 打开文件的正确方式 🛡️

Calling close() yourself is fragile. If an error happens between open and close, the close() line never runs: the file stays open, your writes wait in memory, and on Windows the file stays locked. The with statement (a context manager) closes the file the moment the block ends — even if an error is raised.

close() ख़ुद बुलाना नाज़ुक है। अगर open और close के बीच error आ जाए, तो close() वाली line कभी नहीं चलती: file खुली रहती है, आपके writes memory में इंतज़ार करते हैं, और Windows पर file locked रहती है। with statement (एक context manager) block ख़त्म होते ही file बंद कर देता है — error आने पर भी।

自己调用 close() 很脆弱。如果在 open 和 close 之间发生错误,close() 那一行就永远不会执行:文件保持打开,你写的内容还在内存里等待,在 Windows 上文件还会被锁住。with 语句(一种 上下文管理器)在块结束的那一刻就关闭文件 — 即使抛出了错误。

🚫 The Old, Fragile Wayपुराना, नाज़ुक तरीका老旧、脆弱的方式
Behaviourव्यवहार行为Problemसमस्या问题
close() may be skippedclose() छूट सकता हैclose() 可能被跳过If an error fires, the file stays openError आए तो file खुली रहती है一旦出错,文件保持打开
Manual bookkeepingहाथ से हिसाब手动记账You must close it on every pathहर रास्ते पर बंद करना याद रखना每条路径都得记得关闭
Writes wait in a bufferWrites buffer में रुकते हैं写入停在缓冲区Other programs see old data; a crash loses itदूसरे programs को पुराना data दिखता है; crash में खो जाता है其他程序看到旧数据;崩溃就丢失
File locks lingerFile lock बना रहता है文件锁不释放Other programs can't open it (Windows)दूसरे programs उसे नहीं खोल पाते (Windows)其他程序打不开它(Windows)
✅ The Modern with Wayआधुनिक with तरीका现代的 with 方式
Behaviourव्यवहार行为Benefitफ़ायदा好处
Auto-close when the block endsBlock ख़त्म होते ही अपने-आप बंद块结束时自动关闭Cleanup is guaranteedसफ़ाई पक्की保证清理
Error-safeError में भी सुरक्षित出错也安全Even if code inside raises, the file closesअंदर का code error दे, तब भी file बंद होती है即使内部代码抛错,文件也会关闭
Buffer flushedBuffer flush होता है缓冲区被刷新Writes reach the diskWrites disk तक पहुँचते हैं写入到达磁盘
File handle releasedFile handle छूट जाता है文件句柄被释放Other programs can use it at onceदूसरे programs तुरंत इस्तेमाल कर सकते हैं其他程序可以立即使用
# The old, error-prone pattern - avoid
f = open("notes.txt", "r", encoding="utf-8")
data = f.read()
f.close()                        # skipped if read() raises

# The correct pattern - use this everywhere
with open("notes.txt", "r", encoding="utf-8") as f:
    data = f.read()
# f is guaranteed closed here, even if read() raised
print(f.closed)
print(data)
OUTPUT
True Buy milk Finish tutorial Call mom

Where Do Your Writes Go? The Bufferआपके Writes कहाँ जाते हैं? Buffer你写的内容去哪了?缓冲区

write() does not go straight to the disk. Python collects small writes in a buffer in memory and sends them in one go — much faster. The buffer is emptied to disk ("flushed") when it fills up, when you call flush(), or when the file is closed. This real program proves it:

write() सीधे disk पर नहीं जाता। Python छोटे writes को memory के एक buffer में जमा करता है और एक साथ भेजता है — बहुत तेज़। Buffer disk पर तब ख़ाली ("flush") होता है जब वह भर जाए, जब आप flush() बुलाएँ, या जब file बंद हो। यह असली program इसे साबित करता है:

write() 并不会直接写到磁盘。Python 把小的写入收集在内存中的 缓冲区 里,再一次性写出 — 快得多。缓冲区在写满时、你调用 flush() 时、或文件关闭时才会写到磁盘("刷新")。下面这个真实程序证明了这一点:

# Writes go to a BUFFER in memory first, not straight to the disk
f = open("report.txt", "w", encoding="utf-8")
f.write("line 1\n")

with open("report.txt", encoding="utf-8") as reader:
    print("before close:", repr(reader.read()))   # another reader sees nothing yet

f.close()                                          # close() flushes the buffer

with open("report.txt", encoding="utf-8") as reader:
    print("after close: ", repr(reader.read()))
OUTPUT
before close: '' after close: 'line 1\n'

Try It — Buffer Visualizerकरके देखें — Buffer Visualizer动手试试 — 缓冲区可视化

Step through five short programs and watch three places: the buffer in memory, the file on the disk, and what another program sees when it reads the file. Every outcome here was checked with real Python.

पाँच छोटे programs कदम-दर-कदम चलाएँ और तीन जगहें देखें: memory का buffer, disk पर file, और file पढ़ने पर दूसरे program को क्या दिखता है। यहाँ का हर नतीजा असली Python से जाँचा गया है।

一步步执行五个小程序,观察三个地方:内存中的 缓冲区、磁盘 上的文件,以及 另一个程序 读取文件时看到的内容。这里的每个结果都用真实 Python 验证过。

🧠 Buffer Visualizerwrite() → buffer → disk. Only flush/close moves the data.write() → buffer → disk। Data सिर्फ़ flush/close से आगे बढ़ता है।write() → 缓冲区 → 磁盘。只有 flush/close 才会移动数据。
what print() showsprint() क्या दिखाता हैprint() 的输出
🔑
One Rule to Live Byजीने का एक नियम一条要遵守的规则

If you write open( without with in front of it, stop and ask why. Almost every mature Python codebase uses with for file I/O. (The rare exception: a file you keep open for the whole program, like a long-running log — then you must close it yourself.)

अगर आप open( के आगे with लिखे बिना लिखते हैं, तो रुककर पूछें क्यों। लगभग हर परिपक्व Python codebase file I/O के लिए with इस्तेमाल करता है। (कभी-कभार अपवाद: ऐसी file जो पूरे program भर खुली रहे, जैसे लंबा चलने वाला log — तब उसे ख़ुद बंद करना होगा।)

如果你写了 open( 而前面没有 with,停下来问问为什么。几乎所有成熟的 Python 代码库都用 with 做文件读写。(少见的例外:整个程序运行期间都保持打开的文件,比如长期运行的日志 — 那时你必须自己关闭它。)


SectionSection第 05 节

Reading Files — Four Techniques 📖Files पढ़ना — चार तरीके 📖读取文件 — 四种方法 📖

Python gives you four ways to read a text file. They differ in how much they load at once — which matters a lot when the file is big.

Python text file पढ़ने के चार तरीके देता है। फ़र्क़ इसमें है कि वे एक बार में कितना लोड करते हैं — जो बड़ी file के लिए बहुत मायने रखता है।

Python 提供四种读取文本文件的方法。它们的区别在于一次加载 多少 内容 — 文件很大时这一点非常重要。

📦
read()
whole file → one strपूरी file → एक str整个文件 → 一个 str
Loads the entire file into one string. Simple — but a 2 GB file needs 2 GB+ of memory.
पूरी file को एक string में लोड करता है। आसान — पर 2 GB की file को 2 GB+ memory चाहिए।
把整个文件读进一个字符串。简单 — 但 2 GB 的文件需要 2 GB 以上内存。
➡️
readline()
one line per callहर call में एक line每次调用一行
Returns the next line, including its \n. Returns '' at the end of the file.
अगली line लौटाता है, उसके \n सहित। File के अंत पर '' लौटाता है।
返回下一行,包括 它的 \n。到文件末尾时返回 ''。
📋
readlines()
list of all linesसभी lines की list所有行的列表
Returns a list; each item keeps its \n. Loads everything into memory, like read().
एक list लौटाता है; हर item अपना \n रखता है। read() की तरह सब कुछ memory में लोड करता है।
返回一个列表,每一项都保留 \n。和 read() 一样把全部内容载入内存。
🔁
for line in f:
best for big filesबड़ी files के लिए सबसे अच्छा大文件的最佳选择
Gives one line at a time and keeps only that line in memory. Works the same on a 1 KB or a 10 GB file.
एक बार में एक line देता है और memory में सिर्फ़ वही line रखता है। 1 KB या 10 GB की file पर एक जैसा चलता है।
每次给出一行,内存中只保留这一行。对 1 KB 和 10 GB 的文件效果一样。
# Assume notes.txt contains:
#   Buy milk
#   Finish tutorial
#   Call mom

# 1) read() - everything as one string
with open("notes.txt", encoding="utf-8") as f:
    text = f.read()
    print(repr(text))

# 2) readline() - one line, keeps \n
with open("notes.txt", encoding="utf-8") as f:
    first = f.readline()
    print(repr(first))

# 3) readlines() - list of lines
with open("notes.txt", encoding="utf-8") as f:
    lines = f.readlines()
    print(lines)

# 4) Iterate the file - best for large files
with open("notes.txt", encoding="utf-8") as f:
    for i, line in enumerate(f, 1):
        print(f"{i}: {line.rstrip()}")
OUTPUT
'Buy milk\nFinish tutorial\nCall mom\n' 'Buy milk\n' ['Buy milk\n', 'Finish tutorial\n', 'Call mom\n'] 1: Buy milk 2: Finish tutorial 3: Call mom
✂️
Why .rstrip()?.rstrip() क्यों?为什么用 .rstrip()?

Every line from a file ends with \n (except perhaps the last). print() adds its own newline, so without .rstrip() you get blank lines between rows. Use .rstrip("\n") if you want to keep other trailing spaces. One small exception to "iterating is memory-safe": a file with one gigantic line (say, minified JSON) is still read as one huge string.

File की हर line \n पर ख़त्म होती है (शायद आख़िरी को छोड़कर)। print() अपनी newline जोड़ता है, इसलिए .rstrip() के बिना rows के बीच ख़ाली lines आती हैं। अगर बाक़ी पीछे की spaces रखनी हों तो .rstrip("\n") इस्तेमाल करें। "Iterate करना memory-safe है" का एक छोटा अपवाद: एक बहुत बड़ी line वाली file (जैसे minified JSON) फिर भी एक विशाल string के रूप में पढ़ी जाती है।

文件中的每一行都以 \n 结尾(最后一行可能除外)。print() 会再加一个换行,所以不用 .rstrip() 的话,行与行之间会出现空行。如果想保留其他尾部空格,就用 .rstrip("\n")。"逐行遍历很省内存" 有个小例外:只有一行巨长内容的文件(比如压缩过的 JSON)仍会被读成一个巨大的字符串。

Try It — Read Cursor Labकरके देखें — Read Cursor Lab动手试试 — 读取光标实验室

A file object remembers where it stopped, like a bookmark. Edit the file text, then press the buttons in any order. Watch the orange cursor move and the real return values appear in the console.

File object याद रखता है कि वह कहाँ रुका, एक bookmark की तरह। File का text बदलें, फिर किसी भी क्रम में buttons दबाएँ। नारंगी cursor को चलते और console में असली return values आते देखें।

文件对象会像书签一样 记住它停在哪里。修改文件文本,然后按任意顺序点击按钮。观察橙色光标的移动,以及控制台中出现的真实返回值。

📖 Read Cursor LabOne file, one cursor. Every read starts where the last one stopped.एक file, एक cursor। हर read वहीं से शुरू होता है जहाँ पिछला रुका।一个文件,一个光标。每次读取都从上次停下的地方开始。
notes.txt — edit menotes.txt — मुझे बदलेंnotes.txt — 可编辑

Here is the most common surprise, in real code: reading twice gives an empty string the second time, until you rewind with seek(0).

यह सबसे आम हैरानी है, असली code में: दो बार पढ़ने पर दूसरी बार ख़ाली string मिलती है, जब तक आप seek(0) से पीछे न जाएँ।

这是最常见的意外,用真实代码演示:连读两次,第二次得到空字符串,直到你用 seek(0) 倒回开头。

with open("notes.txt", encoding="utf-8") as f:
    first = f.read()
    second = f.read()            # the cursor is already at the end
    print(len(first), repr(second), f.tell())
    f.seek(0)                    # rewind to the start
    print(repr(f.readline()))
OUTPUT
34 '' 34 'Buy milk\n'

SectionSection第 06 节

Writing Files — write() and writelines() ✍️Files लिखना — write() और writelines() ✍️写入文件 — write() 和 writelines() ✍️

Open with "w" to create or replace a file. write() takes one string and returns how many characters it wrote. Neither method adds newlines for you — that is the job of print(), not of files.

File बनाने या बदलने के लिए "w" से खोलें। write() एक string लेता है और बताता है कि कितने अक्षर लिखे। दोनों में से कोई method आपके लिए newline नहीं जोड़ता — यह print() का काम है, files का नहीं।

用 "w" 打开以创建或替换文件。write() 接收一个字符串,返回写入的字符数。两个方法都不会替你加换行 — 那是 print() 的工作,不是文件的。

# write() - one string at a time. Add \n yourself.
with open("todo.txt", "w", encoding="utf-8") as f:
    f.write("Buy milk\n")
    f.write("Finish tutorial\n")
    n = f.write("Call mom\n")
print("write() returned", n, "(characters written)")

# writelines() - takes an iterable. Still no auto-newlines!
with open("todo2.txt", "w", encoding="utf-8") as f:
    f.writelines(["Buy milk", "Finish tutorial", "Call mom"])

# Idiomatic pattern - join then write once
with open("todo3.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(["Buy milk", "Finish tutorial", "Call mom"]) + "\n")

for name in ["todo.txt", "todo2.txt", "todo3.txt"]:
    with open(name, encoding="utf-8") as f:
        print(name, repr(f.read()))
OUTPUT
write() returned 9 (characters written) todo.txt 'Buy milk\nFinish tutorial\nCall mom\n' todo2.txt 'Buy milkFinish tutorialCall mom' todo3.txt 'Buy milk\nFinish tutorial\nCall mom\n'
⚠️
writelines() Is Misleadingly Namedwritelines() का नाम भ्रामक हैwritelines() 的名字有误导性

Despite the name, writelines() does not add line breaks. It just writes each string one after another — look at todo2.txt above: 'Buy milkFinish tutorialCall mom'. Add the \n yourself, or use "\n".join(...). Also note: in text mode each \n you write becomes the system's line ending (\r\n on Windows).

नाम के बावजूद writelines() line breaks नहीं जोड़ता। यह बस हर string एक के बाद एक लिखता है — ऊपर todo2.txt देखें: 'Buy milkFinish tutorialCall mom'। \n ख़ुद जोड़ें, या "\n".join(...) इस्तेमाल करें। ध्यान दें: text mode में आपका लिखा हर \n system का line-ending बन जाता है (Windows पर \r\n)।

尽管名字如此,writelines() 不会 添加换行。它只是把每个字符串依次写出 — 看上面的 todo2.txt:'Buy milkFinish tutorialCall mom'。请自己加上 \n,或使用 "\n".join(...)。另外注意:文本模式下你写的每个 \n 都会变成系统的行尾符(Windows 上是 \r\n)。

Proof: Mode "w" Wipes Firstसबूत: Mode "w" पहले मिटाता है证明:模式 "w" 会先清空

# Before: todo.txt has 100 important lines
with open("todo.txt", "w", encoding="utf-8") as f:
    f.writelines(f"task {i}\n" for i in range(1, 101))

with open("todo.txt", encoding="utf-8") as f:
    print("lines before:", len(f.readlines()))

# Opening with "w" empties the file at once
with open("todo.txt", "w", encoding="utf-8") as f:
    f.write("just this one line\n")

with open("todo.txt", encoding="utf-8") as f:
    print("lines after: ", len(f.readlines()))   # the other 99 are gone
OUTPUT
lines before: 100 lines after: 1

SectionSection第 07 节

Appending — Add Without Destroying ➕Append करना — बिना मिटाए जोड़ें ➕追加 — 添加而不破坏 ➕

Mode "a" creates the file if needed and puts every write at the end. Old content is never touched. That makes it perfect for logs, audit trails and anything that grows over time.

Mode "a" ज़रूरत हो तो file बनाता है और हर write को अंत में रखता है। पुराने content को कभी नहीं छूता। इसलिए यह logs, audit trails और समय के साथ बढ़ने वाली हर चीज़ के लिए बढ़िया है।

模式 "a" 在需要时创建文件,并把每次写入放在 末尾。旧内容永远不会被碰。所以它非常适合日志、审计记录以及任何随时间增长的内容。

import datetime

def log_event(message):
    now = datetime.datetime.now().isoformat(timespec="seconds")
    with open("app.log", "a", encoding="utf-8") as f:
        f.write(f"[{now}] {message}\n")

log_event("server started")
log_event("user aarav signed in")
log_event("processed 42 requests")

# Read it back
with open("app.log", encoding="utf-8") as f:
    print(f.read(), end="")
OUTPUT
[2026-10-30T16:34:49] server started [2026-10-30T16:34:49] user aarav signed in [2026-10-30T16:34:49] processed 42 requests
🕒
Your Timestamps Will Differआपके Timestamps अलग होंगे你的时间戳会不同

The output above is from a real run, so it shows the time when this page was built. Run it twice and app.log will hold six lines — mode "a" keeps everything from earlier runs.

ऊपर का output असली run का है, इसलिए यह वह समय दिखाता है जब यह page बना। इसे दो बार चलाएँ तो app.log में छह lines होंगी — mode "a" पिछले runs का सब कुछ रखता है।

上面的输出来自一次真实运行,所以显示的是本页面构建时的时间。运行两次的话,app.log 会有六行 — 模式 "a" 会保留之前每次运行的内容。


SectionSection第 08 节

Encodings — Why Your Text Turns Into Garbage 🔤Encodings — आपका Text कचरा क्यों बन जाता है 🔤编码 — 你的文本为什么变成乱码 🔤

The Secret Codebookगुप्त कोडबुक秘密密码本
A disk cannot store letters — only numbers (bytes). An encoding is the codebook that turns letters into bytes when you write, and bytes back into letters when you read. If the writer and the reader use different codebooks, the message comes out as nonsense — or does not come out at all.

UTF-8 is the codebook the whole world has agreed on: it can store every character, from a to é to 王 to 🙂. Until Python 3.15, open() without an encoding= used whatever codebook your computer happened to have — which is how a script that worked fine on Linux broke on a Windows laptop.
Disk अक्षर नहीं रख सकती — सिर्फ़ संख्याएँ (bytes)। Encoding वह कोडबुक है जो लिखते समय अक्षरों को bytes में और पढ़ते समय bytes को वापस अक्षरों में बदलती है। अगर लिखने वाला और पढ़ने वाला अलग कोडबुक इस्तेमाल करें, तो संदेश बकवास बनकर निकलता है — या निकलता ही नहीं।

UTF-8 वह कोडबुक है जिस पर पूरी दुनिया सहमत है: यह हर अक्षर रख सकती है, a से é से 王 से 🙂 तक। Python 3.15 तक, encoding= के बिना open() वही कोडबुक इस्तेमाल करता था जो आपके कंप्यूटर पर हो — इसी वजह से Linux पर ठीक चलने वाला script Windows laptop पर टूट जाता था।
磁盘无法存储字母 — 只能存储数字(字节)。编码 就是一本密码本:写入时把字母变成字节,读取时再把字节变回字母。如果写的人和读的人用的密码本不同,信息就会变成胡言乱语 — 甚至根本读不出来。

UTF-8 是全世界共同认可的密码本:它能存储所有字符,从 a 到 é,到 王,再到 🙂。在 Python 3.15 之前,不写 encoding= 的 open() 会用你电脑碰巧使用的密码本 — 这就是为什么在 Linux 上好好的脚本,到了 Windows 笔记本上就坏了。
# Write with an explicit encoding...
names = ["Sofía", "Zoë", "Björn", "王小明"]
with open("names.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(names) + "\n")

# ...and read with the same one
with open("names.txt", encoding="utf-8") as f:
    for line in f:
        print(line.rstrip())

# Read the SAME bytes with the wrong encoding: garbled text ("mojibake")
with open("names.txt", encoding="cp1252", errors="replace") as f:
    print(f.readline().rstrip())

# Without errors=, the wrong encoding can crash
try:
    with open("names.txt", encoding="ascii") as f:
        f.read()
except UnicodeDecodeError as e:
    print("UnicodeDecodeError:", e)
OUTPUT
Sofía Zoë Björn 王小明 Sofía UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)
🛟
The errors= Parametererrors= Parametererrors= 参数

When bytes do not fit the encoding, errors="strict" (the default) raises an error. errors="replace" puts � in place of bad bytes, and errors="ignore" drops them silently. Use them only for messy input you cannot fix — they hide problems instead of solving them.

जब bytes encoding में फ़िट न हों, तो errors="strict" (default) error देता है। errors="replace" ख़राब bytes की जगह � रखता है, और errors="ignore" उन्हें चुपचाप हटा देता है। इन्हें सिर्फ़ ऐसे गंदे input के लिए इस्तेमाल करें जिसे आप ठीक नहीं कर सकते — ये समस्या हल करने के बजाय छिपाते हैं।

当字节不符合编码时,errors="strict"(默认)会抛出错误。errors="replace" 用 � 代替坏字节,errors="ignore" 则悄悄丢弃它们。只在无法修复的脏数据上使用它们 — 它们是在掩盖问题,而不是解决问题。

Try It — Encoding Labकरके देखें — Encoding Lab动手试试 — 编码实验室

Type any text. Choose the encoding used to write the file and the one used to read it back. Each box is one byte. Try the chips below for the classic disasters.

कोई भी text लिखें। File लिखने की encoding और वापस पढ़ने की encoding चुनें। हर डिब्बा एक byte है। मशहूर गड़बड़ियाँ देखने के लिए नीचे के chips आज़माएँ।

输入任意文本。选择 写入 文件时用的编码和 读回 时用的编码。每个方框是一个字节。试试下面的按钮,看看经典的翻车现场。

🔤 Encoding Labcharacters → bytes → characters. Same codebook both ways, or trouble.अक्षर → bytes → अक्षर। दोनों तरफ़ एक ही कोडबुक, वरना मुसीबत।字符 → 字节 → 字符。两边用同一本密码本,否则就有麻烦。
Try:आज़माएँ:试试:

SectionSection第 09 节

Working with Paths — pathlib 🗺️Paths के साथ काम — pathlib 🗺️处理路径 — pathlib 🗺️

Gluing paths together with + breaks the moment your code runs on another operating system (Windows uses \, Linux and macOS use /). The pathlib module gives you Path objects that join with / and work everywhere. They also have handy shortcuts for small files.

Paths को + से जोड़ना उसी पल टूट जाता है जब आपका code दूसरे operating system पर चलता है (Windows \ इस्तेमाल करता है, Linux और macOS /)। pathlib module आपको Path objects देता है जो / से जुड़ते हैं और हर जगह चलते हैं। छोटी files के लिए इनमें आसान shortcuts भी हैं।

用 + 拼接路径,一旦代码在别的操作系统上运行就会出错(Windows 用 \,Linux 和 macOS 用 /)。pathlib 模块提供 Path 对象,用 / 拼接,到处都能用。它们还为小文件提供了方便的快捷方法。

from pathlib import Path

# Build paths without worrying about \ vs /
data_dir = Path("data")
notes = data_dir / "notes.txt"
print(notes)                     # data/notes.txt (data\notes.txt on Windows)

print("exists?  ", notes.exists())
data_dir.mkdir(exist_ok=True)    # create the folder if needed

# Path has shortcuts for small files
notes.write_text("a new note\n", encoding="utf-8")
print("exists?  ", notes.exists(), "| is file?", notes.is_file())
print("suffix:  ", notes.suffix)
print("stem:    ", notes.stem)
print("parent:  ", notes.parent)

# pathlib plays nicely with open()
with open(notes, encoding="utf-8") as f:
    print(repr(f.read()))
print(repr(notes.read_text(encoding="utf-8")))
OUTPUT
data/notes.txt exists? False exists? True | is file? True suffix: .txt stem: notes parent: data 'a new note\n' 'a new note\n'
Anatomy of a PathPath की बनावट路径的结构
Anatomy of a pathdata/reports/2026/sales.csv.parent.stem.suffix.namePath("data") / "reports" / "2026" / "sales.csv"

.name is the last part; .stem is the name without its extension; .suffix is the extension; .parent is the folder that holds it.

.name आख़िरी हिस्सा है; .stem extension के बिना नाम है; .suffix extension है; .parent वह folder है जिसमें यह है।

.name 是最后一部分;.stem 是去掉扩展名的名字;.suffix 是扩展名;.parent 是包含它的文件夹。

Try It — Path Explorerकरके देखें — Path Explorer动手试试 — 路径探索器

Type any path and see how pathlib splits it up. The table shows the exact values Python gives (using POSIX rules, as on Linux and macOS). Try the tricky ones: hidden files, double extensions, messy slashes.

कोई भी path लिखें और देखें कि pathlib उसे कैसे बाँटता है। Table वही values दिखाती है जो Python देता है (POSIX नियमों से, जैसे Linux और macOS पर)। मुश्किल वाले आज़माएँ: hidden files, दोहरे extensions, बिखरे slashes।

输入任意路径,看看 pathlib 如何拆分它。表格显示的是 Python 给出的确切值(按 POSIX 规则,与 Linux 和 macOS 相同)。试试那些棘手的:隐藏文件、双重扩展名、混乱的斜杠。

🗺️ Path ExplorerOne path, many pieces. pathlib does the splitting for you.एक path, कई टुकड़े। pathlib बाँटने का काम करता है।一个路径,多个部分。pathlib 替你拆分。
Try:आज़माएँ:试试:

SectionSection第 10 节

Handling File Errors Gracefully 🧯File Errors को सलीके से संभालना 🧯优雅地处理文件错误 🧯

Files live outside your program, so things go wrong that your code cannot prevent: a file was deleted, a folder has the wrong permissions, someone saved the data in another encoding. Catch the specific errors you can handle, and let the rest surface.

Files आपके program के बाहर रहती हैं, इसलिए ऐसी गड़बड़ियाँ होती हैं जिन्हें आपका code रोक नहीं सकता: file delete हो गई, folder की permissions ग़लत हैं, किसी ने data दूसरी encoding में save किया। वे ख़ास errors पकड़ें जिन्हें आप संभाल सकते हैं, और बाक़ी को सामने आने दें।

文件存在于程序之外,所以总会发生代码无法阻止的问题:文件被删了,文件夹权限不对,有人用别的编码保存了数据。只捕获你能处理的 具体 错误,其余的让它们暴露出来。

ExceptionException异常When it happensकब होता है何时发生Typical fixआम इलाज常见处理
FileNotFoundErrorOpening a missing file with "r"मौजूद न होने वाली file को "r" से खोलना用 "r" 打开不存在的文件Check the path; create a defaultPath जाँचें; default बनाएँ检查路径;创建默认值
FileExistsErrorMode "x" on a file that existsमौजूद file पर mode "x"对已存在的文件用模式 "x"Pick another name or ask the userदूसरा नाम चुनें या user से पूछें换个名字或询问用户
PermissionErrorNo read/write rights; file locked (Windows)पढ़ने/लिखने का अधिकार नहीं; file locked (Windows)没有读写权限;文件被锁(Windows)Fix permissions; close the other programPermissions ठीक करें; दूसरा program बंद करें修正权限;关闭另一个程序
IsADirectoryErrorThe path is a folder, not a filePath एक folder है, file नहीं路径是文件夹而不是文件Check with Path.is_file()Path.is_file() से जाँचें用 Path.is_file() 检查
UnicodeDecodeErrorBytes do not match the encodingBytes encoding से मेल नहीं खाते字节与编码不匹配Use the right encoding=सही encoding= दें使用正确的 encoding=
OSErrorParent of all the file errors above (except Unicode)ऊपर के सभी file errors का parent (Unicode को छोड़कर)以上所有文件错误的父类(Unicode 除外)Catch-all for any I/O problemकिसी भी I/O समस्या के लिए catch-all捕获任何 I/O 问题
def load_config(path):
    try:
        with open(path, encoding="utf-8") as f:
            return f.read()
    except FileNotFoundError:
        print(f"Config not found at {path}, using defaults")
        return ""
    except PermissionError:
        print(f"No permission to read {path}")
        raise
    except UnicodeDecodeError as e:
        print(f"Encoding problem in {path}: {e}")
        raise

config = load_config("settings.ini")
print(repr(config))
OUTPUT
Config not found at settings.ini, using defaults ''

These are the real messages Python prints for each problem — worth recognising on sight:

ये असली संदेश हैं जो Python हर समस्या पर दिखाता है — इन्हें देखते ही पहचानना अच्छा है:

以下是 Python 针对每个问题打印的真实信息 — 值得一眼认出它们:

import os
os.makedirs("logs", exist_ok=True)
with open("bad.txt", "wb") as f:
    f.write(b"caf\xe9")              # "café" saved in cp1252, not UTF-8

tests = [
    lambda: open("missing.txt", encoding="utf-8"),
    lambda: open("notes.txt", "x", encoding="utf-8"),
    lambda: open("logs", encoding="utf-8"),
    lambda: open("bad.txt", encoding="utf-8").read(),
]
for t in tests:
    try:
        t()
    except OSError as e:
        print(type(e).__name__, "->", e)
    except UnicodeDecodeError as e:
        print(type(e).__name__, "->", e)
OUTPUT
FileNotFoundError -> [Errno 2] No such file or directory: 'missing.txt' FileExistsError -> [Errno 17] File exists: 'notes.txt' IsADirectoryError -> [Errno 21] Is a directory: 'logs' UnicodeDecodeError -> 'utf-8' codec can't decode byte 0xe9 in position 3: unexpected end of data
🪟
Windows Is a Little DifferentWindows थोड़ा अलग हैWindows 有点不同

On Windows, opening a folder as a file raises PermissionError instead of IsADirectoryError, and the messages say [Errno 13] or [WinError ...]. Catching OSError covers both systems.

Windows पर folder को file की तरह खोलने से IsADirectoryError की जगह PermissionError आता है, और संदेशों में [Errno 13] या [WinError ...] लिखा होता है। OSError पकड़ने से दोनों systems संभल जाते हैं।

在 Windows 上,把文件夹当文件打开会抛出 PermissionError 而不是 IsADirectoryError,信息里写的是 [Errno 13] 或 [WinError ...]。捕获 OSError 可以同时覆盖两种系统。

🙈
Don't Write a Blanket exceptसब कुछ ढकने वाला except न लिखें不要写一网打尽的 except

A bare except: catches everything — even KeyboardInterrupt (Ctrl+C) and SystemExit, so you can no longer stop your own program. except Exception: is less extreme (it lets Ctrl+C through), but it still hides real bugs such as a TypeError in your own code. Name the exceptions you expect, and let the rest crash loudly where you can see them.

खाली except: सब कुछ पकड़ लेता है — KeyboardInterrupt (Ctrl+C) और SystemExit भी, जिससे आप अपना ही program रोक नहीं पाते। except Exception: कम चरम है (Ctrl+C को जाने देता है), पर फिर भी असली bugs छिपाता है, जैसे आपके अपने code का TypeError। जिन exceptions की उम्मीद है उनके नाम लिखें, और बाक़ी को ज़ोर से crash होने दें जहाँ आप उन्हें देख सकें।

裸 except: 会捕获 一切 — 连 KeyboardInterrupt(Ctrl+C)和 SystemExit 也不放过,你甚至无法停止自己的程序。except Exception: 没那么极端(它会放过 Ctrl+C),但仍然会掩盖真正的 bug,比如你自己代码里的 TypeError。写出你预期的异常名称,让其他异常大声崩溃,好让你看见。


SectionSection第 11 节

Common Pitfalls — and How to Dodge Them 🕳️आम गड्ढे — और उनसे कैसे बचें 🕳️常见陷阱 — 以及如何避开 🕳️

💣
Opening with "w" by accidentग़लती से "w" से खोलना误用 "w" 打开
data lossdata का नुक़सान数据丢失
The file is emptied the moment it opens. Use "a" to add, or "x" to be sure you never overwrite.
File खुलते ही ख़ाली हो जाती है। जोड़ने के लिए "a", या कभी overwrite न हो इसके लिए "x" इस्तेमाल करें।
文件一打开就被清空。追加用 "a",想确保绝不覆盖就用 "x"。
🔤
Forgetting encoding=encoding= भूलना忘记写 encoding=
works on my machineमेरी मशीन पर चलता है在我电脑上没问题
Before Python 3.15 the default depends on the computer. Always write encoding="utf-8".
Python 3.15 से पहले default कंप्यूटर पर निर्भर है। हमेशा encoding="utf-8" लिखें।
Python 3.15 之前,默认值取决于电脑。总是写上 encoding="utf-8"。
🔁
Reading twiceदो बार पढ़ना读两次
empty second timeदूसरी बार ख़ाली第二次为空
The cursor stays at the end after the first read. Use seek(0), or keep the first result in a variable.
पहले read के बाद cursor अंत पर रहता है। seek(0) इस्तेमाल करें, या पहला result एक variable में रखें।
第一次读取后光标停在末尾。用 seek(0),或把第一次的结果存到变量里。
↩️
Missing \n\n छूट जाना漏掉 \n
one long lineएक लंबी line变成一长行
write() and writelines() never add newlines. Add them yourself.
write() और writelines() कभी newline नहीं जोड़ते। ख़ुद जोड़ें।
write() 和 writelines() 从不添加换行。请自己加上。
🐘
read() on huge filesबड़ी files पर read()对大文件用 read()
MemoryErrorMemoryErrorMemoryError
Loop with for line in f: so only one line is in memory at a time.
for line in f: से loop करें ताकि memory में एक बार में एक ही line रहे।
用 for line in f: 循环,这样内存中每次只有一行。
📍
Relative path surprisesRelative path की हैरानी相对路径的意外
FileNotFoundErrorFileNotFoundErrorFileNotFoundError
A relative path starts from the folder you ran Python in, not the folder the script is in. Use Path(__file__).parent / "data.txt".
Relative path उस folder से शुरू होता है जहाँ से आपने Python चलाया, न कि जहाँ script रखी है। Path(__file__).parent / "data.txt" इस्तेमाल करें।
相对路径从你 运行 Python 的文件夹开始,而不是脚本所在的文件夹。请用 Path(__file__).parent / "data.txt"。

SectionSection第 12 节

Putting It All Together — A Word-Frequency Report 🧩सब कुछ एक साथ — शब्द-गिनती की Report 🧩综合运用 — 词频报告 🧩

This small program uses everything from the tutorial: it reads an article line by line, writes a fresh report with "w", appends a line to an audit log with "a", handles a missing file, and uses pathlib to show the log.

यह छोटा program tutorial की हर चीज़ इस्तेमाल करता है: यह एक article को line-by-line पढ़ता है, "w" से नई report लिखता है, "a" से audit log में एक line जोड़ता है, मौजूद न होने वाली file संभालता है, और log दिखाने के लिए pathlib इस्तेमाल करता है।

这个小程序用到了本教程的所有内容:逐行 读取 一篇文章,用 "w" 写入 一份新报告,用 "a" 向审计日志 追加 一行,处理文件不存在的情况,并用 pathlib 显示日志。

01
📖 read
article.txt, one line at a time
article.txt, एक बार में एक line
article.txt,每次一行
02
🧮 count
lower-case, strip punctuation, Counter
lower-case, punctuation हटाएँ, Counter
转小写,去标点,Counter 计数
03
✍️ write "w"
report.txt — replaced every run
report.txt — हर run में बदली जाती है
report.txt — 每次运行都替换
04
➕ append "a"
runs.log — grows every run
runs.log — हर run में बढ़ती है
runs.log — 每次运行都增长
import string
from collections import Counter
from pathlib import Path

def count_words(source_path, report_path, top_n=10):
    counter = Counter()
    translator = str.maketrans("", "", string.punctuation)

    # READ - line by line, so file size does not matter
    try:
        with open(source_path, encoding="utf-8") as f:
            for line in f:
                cleaned = line.lower().translate(translator)
                counter.update(cleaned.split())
    except FileNotFoundError:
        print(f"Source file not found: {source_path}")
        return

    top = counter.most_common(top_n)

    # WRITE - overwrite the report file each run
    with open(report_path, "w", encoding="utf-8") as f:
        f.write(f"Top {top_n} words in {source_path}\n")
        f.write("=" * 40 + "\n")
        for rank, (word, count) in enumerate(top, 1):
            f.write(f"{rank:2d}. {word:15s} {count}\n")

    # APPEND - log this run to an audit file
    with open("runs.log", "a", encoding="utf-8") as f:
        total = sum(counter.values())
        f.write(f"Processed {source_path}: {total} words, {len(counter)} unique\n")

    # Show summary to caller
    print(f"Report written to {report_path}")
    for rank, (word, count) in enumerate(top, 1):
        print(f"  {rank:2d}. {word:15s} {count}")


count_words("article.txt", "report.txt", top_n=5)
print(Path("runs.log").read_text(encoding="utf-8"), end="")
OUTPUT
Report written to report.txt 1. the 16 2. a 10 3. file 9 4. and 4 5. to 4 Processed article.txt: 109 words, 58 unique
report.txt
Top 5 words in article.txt ======================================== 1. the 16 2. a 10 3. file 9 4. and 4 5. to 4

SectionSection第 13 节

Golden Rules and Quick Quiz 🏆सुनहरे नियम और छोटा Quiz 🏆黄金法则与小测验 🏆

📒 File Handling — Rules to RememberFile Handling — याद रखने वाले नियम文件处理 — 必须记住的规则
1
Always open files with with. It closes and flushes for you, even when an error is raised.
Files हमेशा with से खोलें। यह आपके लिए बंद और flush करता है, error आने पर भी।
始终用 with 打开文件。即使出错,它也会替你关闭和刷新。
2
Always pass encoding="utf-8" for text files — it works the same on every system and every Python version.
Text files के लिए हमेशा encoding="utf-8" दें — यह हर system और हर Python version पर एक जैसा चलता है।
文本文件始终传入 encoding="utf-8" — 它在所有系统和所有 Python 版本上表现一致。
3
Think twice before mode "w": it empties the file at once. Use "a" to add and "x" to create safely.
Mode "w" से पहले दो बार सोचें: यह file तुरंत ख़ाली कर देता है। जोड़ने के लिए "a" और सुरक्षित बनाने के लिए "x" इस्तेमाल करें।
用模式 "w" 之前三思:它会立即清空文件。追加用 "a",安全创建用 "x"。
4
Loop with for line in f: for big files. Use read() only when the file is small.
बड़ी files के लिए for line in f: से loop करें। read() सिर्फ़ छोटी file के लिए।
大文件用 for line in f: 循环。只有小文件才用 read()。
5
Add \n yourself when writing. Strip it with .rstrip("\n") when reading.
लिखते समय \n ख़ुद जोड़ें। पढ़ते समय .rstrip("\n") से हटाएँ।
写入时自己加 \n。读取时用 .rstrip("\n") 去掉它。
6
Build paths with pathlib.Path and /, never by gluing strings.
Paths pathlib.Path और / से बनाएँ, strings जोड़कर कभी नहीं।
用 pathlib.Path 和 / 构建路径,永远不要拼接字符串。
7
Catch specific errors (FileNotFoundError, PermissionError…), never a bare except:.
ख़ास errors पकड़ें (FileNotFoundError, PermissionError…), कभी खाली except: नहीं।
捕获具体的错误(FileNotFoundError、PermissionError……),绝不用裸 except:。

Quick Quiz — 7 Questionsछोटा Quiz — 7 सवाल小测验 — 7 道题

🏆 QuizPick an answer to see why.जवाब चुनें और कारण देखें।选一个答案,看看原因。
🎯
Key Takeawayमुख्य सीख关键要点

File handling is three steps — open, read or write, close — and with open(path, mode, encoding="utf-8") as f: does all three safely. Pick the mode on purpose, remember the cursor, add your own newlines, and catch the specific errors you can fix. With that, your programs can finally remember things.

File handling तीन कदम है — खोलें, पढ़ें या लिखें, बंद करें — और with open(path, mode, encoding="utf-8") as f: तीनों को सुरक्षित रूप से करता है। Mode सोच-समझकर चुनें, cursor याद रखें, newlines ख़ुद जोड़ें, और वे ख़ास errors पकड़ें जिन्हें आप ठीक कर सकते हैं। इतना करें, तो आपके programs आख़िरकार चीज़ें याद रख सकते हैं।

文件处理就是三步 — 打开、读或写、关闭 — 而 with open(path, mode, encoding="utf-8") as f: 能安全地完成这三步。有意识地选择模式,记住光标,自己加换行,捕获你能修复的具体错误。做到这些,你的程序终于能记住东西了。

🐍 Try Python Yourself

Write, run and visualize Python step by step. No install needed.