Why File Handling Matters — Programs That Remember 📒File Handling क्यों ज़रूरी है — याद रखने वाले Programs 📒为什么文件处理很重要 — 会记忆的程序 📒
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.
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)。本教程专注于文本文件,它们覆盖了日常脚本中的大部分需求。
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 语句(虚线框)会替你完成关闭。
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 语句会替你完成这个仪式 — 几乎每次都应该使用它。
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 本身核对过。
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)
open()open() की बनावटopen() 的结构pathlib.Path.
File कहाँ है — notes.txt जैसा relative नाम या /var/log/app.log जैसा पूरा path। String या pathlib.Path हो सकता है।
文件在哪里 — 像 notes.txt 这样的相对名字,或像 /var/log/app.log 这样的完整路径。可以是字符串或 pathlib.Path。
\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 会变成系统的行尾符。
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" 在每个版本上都有效,也让每位读者明白你的意图。
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अंत末尾 |
"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 的样子,再选择要做的操作。观察磁盘上的文件(每个方框是一个字符,↵ 是换行)和橙色的 光标 — 下一次读或写发生的位置。
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))
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 语句(一种 上下文管理器)在块结束的那一刻就关闭文件 — 即使抛出了错误。
| 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) |
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)
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()))
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 验证过。
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 做文件读写。(少见的例外:整个程序运行期间都保持打开的文件,比如长期运行的日志 — 那时你必须自己关闭它。)
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()readline()\n. Returns '' at the end of the file.\n सहित। File के अंत पर '' लौटाता है।\n。到文件末尾时返回 ''。readlines()\n. Loads everything into memory, like read().\n रखता है। read() की तरह सब कुछ memory में लोड करता है।\n。和 read() 一样把全部内容载入内存。for line in f:# 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()}")
.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 आते देखें।
文件对象会像书签一样 记住它停在哪里。修改文件文本,然后按任意顺序点击按钮。观察橙色光标的移动,以及控制台中出现的真实返回值。
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()))
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()))
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
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="")
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" 会保留之前每次运行的内容。
Encodings — Why Your Text Turns Into Garbage 🔤Encodings — आपका Text कचरा क्यों बन जाता है 🔤编码 — 你的文本为什么变成乱码 🔤
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.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)
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 आज़माएँ।
输入任意文本。选择 写入 文件时用的编码和 读回 时用的编码。每个方框是一个字节。试试下面的按钮,看看经典的翻车现场。
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")))
.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 相同)。试试那些棘手的:隐藏文件、双重扩展名、混乱的斜杠。
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आम इलाज常见处理 |
|---|---|---|
FileNotFoundError | Opening a missing file with "r"मौजूद न होने वाली file को "r" से खोलना用 "r" 打开不存在的文件 | Check the path; create a defaultPath जाँचें; default बनाएँ检查路径;创建默认值 |
FileExistsError | Mode "x" on a file that existsमौजूद file पर mode "x"对已存在的文件用模式 "x" | Pick another name or ask the userदूसरा नाम चुनें या user से पूछें换个名字或询问用户 |
PermissionError | No read/write rights; file locked (Windows)पढ़ने/लिखने का अधिकार नहीं; file locked (Windows)没有读写权限;文件被锁(Windows) | Fix permissions; close the other programPermissions ठीक करें; दूसरा program बंद करें修正权限;关闭另一个程序 |
IsADirectoryError | The path is a folder, not a filePath एक folder है, file नहीं路径是文件夹而不是文件 | Check with Path.is_file()Path.is_file() से जाँचें用 Path.is_file() 检查 |
UnicodeDecodeError | Bytes do not match the encodingBytes encoding से मेल नहीं खाते字节与编码不匹配 | Use the right encoding=सही encoding= दें使用正确的 encoding= |
OSError | Parent 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))
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)
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 可以同时覆盖两种系统。
exceptसब कुछ ढकने वाला except न लिखें不要写一网打尽的 exceptA 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。写出你预期的异常名称,让其他异常大声崩溃,好让你看见。
Common Pitfalls — and How to Dodge Them 🕳️आम गड्ढे — और उनसे कैसे बचें 🕳️常见陷阱 — 以及如何避开 🕳️
"w" by accidentग़लती से "w" से खोलना误用 "w" 打开"a" to add, or "x" to be sure you never overwrite."a", या कभी overwrite न हो इसके लिए "x" इस्तेमाल करें।"a",想确保绝不覆盖就用 "x"。encoding=encoding= भूलना忘记写 encoding=encoding="utf-8".encoding="utf-8" लिखें।encoding="utf-8"。seek(0), or keep the first result in a variable.seek(0) इस्तेमाल करें, या पहला result एक variable में रखें।seek(0),或把第一次的结果存到变量里。\n\n छूट जाना漏掉 \nwrite() and writelines() never add newlines. Add them yourself.write() और writelines() कभी newline नहीं जोड़ते। ख़ुद जोड़ें।write() 和 writelines() 从不添加换行。请自己加上。read() on huge filesबड़ी files पर read()对大文件用 read()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: 循环,这样内存中每次只有一行。Path(__file__).parent / "data.txt".Path(__file__).parent / "data.txt" इस्तेमाल करें।Path(__file__).parent / "data.txt"。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 显示日志。
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="")
Golden Rules and Quick Quiz 🏆सुनहरे नियम और छोटा Quiz 🏆黄金法则与小测验 🏆
with. It closes and flushes for you, even when an error is raised.with से खोलें। यह आपके लिए बंद और flush करता है, error आने पर भी।with 打开文件。即使出错,它也会替你关闭和刷新。encoding="utf-8" for text files — it works the same on every system and every Python version.encoding="utf-8" दें — यह हर system और हर Python version पर एक जैसा चलता है।encoding="utf-8" — 它在所有系统和所有 Python 版本上表现一致。"w": it empties the file at once. Use "a" to add and "x" to create safely."w" से पहले दो बार सोचें: यह file तुरंत ख़ाली कर देता है। जोड़ने के लिए "a" और सुरक्षित बनाने के लिए "x" इस्तेमाल करें।"w" 之前三思:它会立即清空文件。追加用 "a",安全创建用 "x"。for line in f: for big files. Use read() only when the file is small.for line in f: से loop करें। read() सिर्फ़ छोटी file के लिए।for line in f: 循环。只有小文件才用 read()。\n yourself when writing. Strip it with .rstrip("\n") when reading.\n ख़ुद जोड़ें। पढ़ते समय .rstrip("\n") से हटाएँ।\n。读取时用 .rstrip("\n") 去掉它。pathlib.Path and /, never by gluing strings.pathlib.Path और / से बनाएँ, strings जोड़कर कभी नहीं।pathlib.Path 和 / 构建路径,永远不要拼接字符串。FileNotFoundError, PermissionError…), never a bare except:.FileNotFoundError, PermissionError…), कभी खाली except: नहीं।FileNotFoundError、PermissionError……),绝不用裸 except:。Quick Quiz — 7 Questionsछोटा Quiz — 7 सवाल小测验 — 7 道题
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: 能安全地完成这三步。有意识地选择模式,记住光标,自己加换行,捕获你能修复的具体错误。做到这些,你的程序终于能记住东西了。