尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Python文件操作实战:从文本读写到CSV/JSON处理(day13)

发布时间:2026/9/24 22:32:41

资讯中心
01
ARTICLE

Python文件操作实战:从文本读写到CSV/JSON处理(day13)

Python文件操作实战:从文本读写到CSV/JSON处理(day13)
学了 12 天的 Python 基础语法是时候做点“真事”了。前面我们把变量赋值、类型转换、流程控制、函数这些零件都过了一遍但说实话只会跑终端 demo 的 Python还不算会写程序。真正写程序大多数时间都在跟数据打交道而数据大部分时候都躺在文件里。所以从今天这个 day13 开始我打算把重心从“语法点”转向“真实任务”第一个要啃下的硬骨头就是文件操作与数据处理。读完这篇你能学会用 Python 优雅地读写文本文件处理 CSV 成绩单、JSON 配置文件还能写一个日志筛选小工具——这些技能不管以后做爬虫、数据分析还是 Web 开发全都用得上。1. 为什么第13天要开始死磕文件读写1.1 文件操作是整个 Python 生态的地基Python 现在最火的方向无外乎三个爬虫、数据分析、Web 开发。你仔细想想这三个方向有个共同点——它们的本质都是在跟数据打交道而数据不可能永远飘在内存里最终都要落盘到文件。爬虫抓取下来的商品信息要存成 CSV 或 JSON数据分析师拿到手的原始数据大概率是 Excel 或 CSV 文件Web 服务跑起来之后日志要写进文件配置要读文件缓存可能也要临时落到磁盘上。哪怕你只是写个自动化脚本比如批量重命名文件、定时清理临时目录底层也全是文件操作。所以我一直跟初学者强调文件读写不是 Python 的一个“可选章节”而是地基中的地基。你可以不会写装饰器可以暂时看不懂闭包但如果你不会读写文件那几乎任何一个真实项目都做不了。day13 选在这个时间点切入也正是因为你已经有了变量、函数、流程控制这些基础正好可以把文件操作作为第一个“综合性实战主题”。1.2 一个主题串起前面 12 天所有知识文件操作这个主题奇妙的地方在于它几乎能把前面 12 天学的所有东西都串起来。打开一个文件读进来的数据默认是字符串想把“123”变成数字去做运算就用到类型转换。文件里通常不止一行数据逐行处理后往往要用列表或字典来暂存要遍历每一行就用到 for 循环要过滤掉异常数据就用 if 判断为了避免代码重复把处理逻辑抽成函数又很自然。所以你不是在学一个孤立的新语法而是在做一场“知识总动员”。这套课程从 day1 走到 day12一直有读者反馈说“单独每个语法都懂但一合起来就不会用了”。这很正常因为零散的语法点就像散落一地的乐高零件而文件操作就是你的第一张拼装图纸。当你写出一段代码先读文件、再循环处理、最后写回结果你会突然发现“原来前面的语法是这么配合工作的”这种“开窍”的感觉就是第 13 天最大的收获。1.3 今天的学习地图4 个实战案例这一天内容不算多但每一个都值得动手敲一遍。我按难度从小到大给你排好了顺序。open 函数和 with 语句的核心原理这是所有文件操作的底层基础。文本文件的写入与逐行读取先解决“能不能读写”的问题。CSV 和 JSON 这两种结构化数据的处理解决“数据怎么组织”的问题。一个日志筛选的小案例把前面所有东西融进一个真实场景。为什么要按这个顺序因为文件操作天然是分层递进的。你连文本读写都没搞清楚直接去搞 CSV 会一头雾水你连 CSV 的列都还不会处理直接去分析日志更会手足无措。今天这 4 个案例走完你会发现文件处理在你的脑子里不再是“一个 open 函数”而是一条完整的链路定位文件 → 打开文件 → 读取/解析 → 处理数据 → 写回结果。2. 核心细节从 open() 到 with把文件读写吃透2.1 open() 函数的模式参数理解这 5 种就够用Python 内置的 open() 函数是打开文件唯一需要掌握的门面。它的第一个参数是文件路径第二个参数是打开模式 mode。很多初学者看到官方文档里列的一大堆模式容易头大其实日常工作里只要理解这 5 种模式作用注意点r只读文件必须存在否则报 FileNotFoundErrorw写入会先清空原文件内容不存在则新建a追加不清空原内容从文件末尾写入rb / wb二进制读/写处理图片、视频、压缩包等非文本文件r / w读写兼用语法上可行但新手容易踩指针位置的坑不建议优先学我想重点提醒一下 w 模式和 a 模式的区别这个基础却特别重要。w 是“覆盖写”一旦执行文件原来的内容就会被清空。我见过不止一个新手本来想往配置里加一行结果用了 w 模式整个文件被清空了。如果你是想在日志后面追加新内容一定用 a 模式只有当你确定要“从零重新生成”一个文件时才用 w。r 这种读写混合模式说实话我在实际项目里用得很少。因为读和写的文件指针位置不同很容易出现“写完读不到”“读的位置不对”这种莫名其妙的问题。新手阶段你就老老实实分开读取用 r写入用 w 或 a这样思路最清晰。2.2 为什么推荐用 with 而不是 openclose看很多老代码你会看到这样的写法f open(demo.txt, w, encodingutf-8) f.write(hello) f.close()这种写法不是不行但有个大坑如果你在 write 之后、close 之前程序突然抛了异常close 这一行就不会执行。文件没关会怎样写入的数据可能还留在缓冲区里没真正落到磁盘程序退出后文件内容还是空的或者文件一直被程序占用你去删文件会提示“文件正在使用中”严重时甚至会导致内存或文件句柄泄漏。所以现代 Python 强烈推荐用 with 上下文管理器with open(demo.txt, w, encodingutf-8) as f: f.write(hello)with 语句的原理其实不复杂它会在代码块执行结束后自动帮我们调用 close()哪怕中间抛了异常也会做清理工作。这段代码跑完文件一定被正确关闭你不用再手动操心。很多人刚开始不理解这个 with 为什么叫“上下文管理器”我的理解方式很简单你看这个英文单词 with它表达的就是“在某个场境内做某事”。你进了一个房间办完事出门房间会自动锁好你不需要自己记得回头锁门。这个理念在后端开发里非常常见早点养成用 with 的习惯后面学数据库连接、网络请求时都会轻松很多。2.3 编码与类型转换最容易踩的两颗雷文件操作里最容易让人崩溃的就是编码问题。你写代码时明明觉得没问题一运行却给你抛一个 UnicodeDecodeError或者写出来的文件打开全是乱码这种经历我敢说每个 Python 开发者都遇到过。问题的根源在于不同平台、不同软件生成的文件编码可能不一样。常见的编码有 UTF-8 和 GBK。Windows 上某些老软件默认用 GBK 编码而 Linux 系统和大部分现代工具默认用 UTF-8。Python 在读取文件时如果不指定编码不同平台上默认值还不一样这就导致了“在你电脑上好好的换台电脑就乱码”。我的建议是每次调用 open() 读写文本文件都显式写上 encodingutf-8。这个习惯能帮你避开 90% 的编码坑。如果读的是老系统生成的 GBK 文件就改成 encodinggbk一时分不清是什么编码可以先试 utf-8报错了再换 gbk。第二颗雷是类型转换。从文件里读出来的每一行、每一个单元格本质上都是字符串。你想拿“123”去加 1必须先 int(123)你想拿“3.14”去做浮点运算必须先 float(3.14)。这听起来很简单但实际数据里经常混着空格、换行、特殊字符直接转换就会抛 ValueError。所以完整流程往往是先 strip() 清理空白再转换成目标类型如果数据本身可能是脏数据再加个 try/except 兜底。今天下面的案例里你会看到这个模式反复出现。3. 实操环节四个案例带你从读写到处理3.1 案例一文本文件写入与逐行读取先来一个最基础的往 demo.txt 里写入三行文字再把它读出来打印到屏幕上。with open(demo.txt, w, encodingutf-8) as f: f.write(第一行内容\n) f.write(第二行内容\n) f.write(第三行内容\n)这三行代码做了几件事打开文件、写三行文字、自动关闭文件。注意每行末尾的 \n它是换行符告诉文件“这一行到这里结束”。如果不写 \n三行文字会挤成一行。写入后我们再读取with open(demo.txt, r, encodingutf-8) as f: for line in f: print(line.strip())这里有一个键盘上找不到的细节直接 for line in f 是 Python 里逐行读取文件最优雅的方式。它每次只读一行不会一次性把整个大文件加载进内存哪怕文件有 1 个 G 也能从容处理。这也回答了很多人问的“大文件怎么读”的问题——用 for 循环逐行读而不是 readlines() 把整个文件一次读进来。为什么要 line.strip()因为每行末尾带着 \n 换行符直接 print(line) 会多打一个空行。strip() 会把字符串首尾的空格、换行、制表符都清掉输出就干净了。这个习惯在处理真实数据时非常重要因为真实文件里几乎每一行都带着你不想要的空白字符。3.2 案例二CSV 成绩单的清洗与统计接下来进入结构化数据处理。CSV 是纯文本格式的表格数据每行是一条记录每列用逗号分隔是数据交换场景里最常用的格式之一。假设我们有一个 scores.csv 文件内容是name,math,english,python 张三,88,76,92 李四,59,68,72 王五,90,85,88现在要读进来算出每个人的总分和平均分写到一个新文件 result.csv 里。import csv with open(scores.csv, r, encodingutf-8) as f: reader csv.DictReader(f) rows [] for row in reader: name row[name].strip() math int(row[math].strip()) english int(row[english].strip()) python int(row[python].strip()) total math english python avg round(total / 3, 2) rows.append([name, math, english, python, total, avg]) with open(result.csv, w, encodingutf-8, newline) as f: writer csv.writer(f) writer.writerow([name, math, english, python, total, avg]) writer.writerows(rows)这个案例里有两个很实用的知识点。第一个是 csv.DictReader。它会把 CSV 的表头第一行自动变成字典的 key之后每一行数据都会以字典形式返回row[name] 就能拿到姓名。这样做的好处是不用死记“第 0 列是姓名第 1 列是数学成绩”代码可读性大大提升。第二个是 writer 打开文件时为什么要加 newline。这个坑特别隐蔽——如果不加写出来的 CSV 每隔一行就会出现一个空行。原因是 csv 模块自己会处理换行符和 open() 的默认换行行为冲突了。我见过很多朋友在这里卡了半天明明代码逻辑都对就是输出文件多了一堆空行。记住操作 CSV 文件时加 newline 是一个标准姿势。数据处理方面你看 int(row[math].strip()) 这行先 strip() 清掉两侧可能存在的空格再转 int。真实 CSV 文件里单元格前后经常藏着空格、回车不清理就会抛 ValueError。这就是前面说的“类型转换的雷”在真实场景里几乎每次都会遇到。3.3 案例三JSON 配置文件的读取与修改JSON 是另一种极其常见的数据格式它的特点是可以嵌套表达能力比 CSV 强很多特别适合存配置。做爬虫的同学应该很熟悉请求头、延迟时间、账号密码之类的参数通常都会放在一个 config.json 里。假设 config.json 内容如下{ url: https://example.com/api, interval: 3, headers: { User-Agent: python-requests } }现在要把 interval 改成 5同时改一下 User-Agent再写回文件import json with open(config.json, r, encodingutf-8) as f: config json.load(f) config[interval] 5 config[headers][User-Agent] Mozilla/5.0 with open(config.json, w, encodingutf-8) as f: json.dump(config, f, ensure_asciiFalse, indent2)json.load 会把 JSON 文件自动还原成 Python 的字典和列表你直接就能通过 key 修改值非常直观。修改完成后json.dump 再把它写回文件。写回的时候有两个参数值得关注。第一个是 ensure_asciiFalse如果不设置它中文会被转成 \uXXXX 这种转义序列文件内容完全没法看。第二个是 indent2让 JSON 输出有缩进文件可读性好很多。少了这两个参数代码也能跑但产出的文件丑得你不想打开第二次。还有个小经验读取不熟悉的 JSON 配置文件时先用 print(config.keys()) 看一眼它有哪些顶层字段再动手改。我曾经凭记忆“我觉得字段叫 interval”结果实际文件里写的是 “time_interval”一运行直接 KeyError。先打印结构是处理嵌套 JSON 时最稳妥的起步动作。3.4 案例四日志文件的筛选与统计最后一个案例我们写一个日志分析的小工具。假设 server.log 文件内容大致是这样2025-01-01 10:00:00 INFO 服务启动成功 2025-01-01 10:00:05 ERROR 数据库连接超时 2025-01-01 10:00:08 INFO 重试中 2025-01-01 10:00:12 ERROR 数据库连接超时 2025-01-01 10:00:20 ERROR 磁盘空间不足我们要统计 ERROR 的总数并把所有包含“超时”的行打印出来error_count 0 with open(server.log, r, encodingutf-8) as f: for line in f: if ERROR in line: error_count 1 if 超时 in line: print(line.strip()) print(ERROR 总数:, error_count)这段代码没什么高深语法但非常“程序员”。你会发现真实世界的日志处理很多时候就是这种朴素的关键字判断。等以后学了正则表达式你能用 re 模块提取时间戳、IP 地址做更精确的分析学了 pandas你能按小时、按天聚合统计错误数量。但今天这个版本已经是一个能解决实际问题的“最小可用方案”。另外你可以试着把这段代码封装成一个函数比如 analyze_log(filepath, keyword)。这就在实际项目中养成了好习惯每个小工具都是一个独立函数参数通过函数的入参传递方便复用和测试。这也是前面学的“函数”知识第一次和文件处理真正结合。4. 常见问题速查表与避坑经验4.1 新手最容易遇到的 6 个报错文件操作报错率极高我把最常见的问题整理成一张速查表建议你保存起来报错信息出现原因解决办法FileNotFoundError文件不存在或当前工作目录和你以为的不一样先检查文件路径用 os.path.exists() 判断打印 os.getcwd() 看当前目录UnicodeDecodeError读取时的编码与实际文件编码不一致显式指定 encodingutf-8如果不行再试 gbkUnicodeEncodeError写入时编码设置不合理写入也显式指定 encodingutf-8PermissionError文件被其他程序占用或没有写入权限关闭占用程序或换个可写目录ValueErrorint 转换失败数据里有空格、换行或非数字字符先 strip()再转换必要时 try/except 兜底CSV 每两行空一行打开文件时没加 newline写入 CSV 时 open 里加 newline这六个里面FileNotFoundError 是我被问得最多的。很多人代码明明看着没问题为什么找不到文件因为 open 里面的相对路径是相对于“当前工作目录”的而不是“Python 文件所在目录”。你可能从桌面运行脚本工作目录就是桌面而你写的 demo.txt 在别的文件夹里自然找不到。遇到这种情况要么用绝对路径要么打印 os.getcwd() 看看当前工作目录到底是什么。4.2 三个让我少踩很多坑的实操习惯做文件处理做得多了我慢慢养成了一些固定习惯谈不上高大上但确实帮我省了不少时间。第一个习惯是任何时候读写文本文件都显式写 encodingutf-8。哪怕是在 Linux 上哪怕 Python 默认就是 utf-8我也写。因为你不知道这段代码几个月后会被谁在什么系统上运行写死编码就是给未来的自己少挖一个坑。第二个习惯是涉及文件路径时尽量用 os.path.join() 来拼接而不是手动写 data/ filename 这种字符串。因为 Windows 用反斜杠Linux 和 macOS 用正斜杠手动拼接很容易跨平台出问题。os.path.join(data, scores.csv) 会自动选择当前平台正确的分隔符。第三个习惯是有风险的文件写入场景先写临时文件再替换。比如你有一个重要的配置文件程序要修改它如果你直接以 w 模式打开原文件写入万一写到一半程序崩了原文件就坏了。稳妥的做法是先写到一个临时文件比如 config.json.tmp写成功后用 os.replace() 把它替换成正式文件。这个习惯在写生产环境脚本时尤其重要我第一次体会到它的价值就是在一次程序崩溃后眼睁睁看着配置文件被写坏那叫一个痛。5. 文件操作的能力如何给后续学习铺路5.1 爬虫与数据分析都会用到这些很多人学文件操作时会觉得就这么点东西有什么好学的但我想说今天你练的每一个案例几乎都能在后面的主流方向里直接复用。先说爬虫。写爬虫抓取数据代码其实只占 30%剩下 30% 是数据清洗40% 是把数据存下来。存数据逃不开 csv.writer、json.dump 这两板斧。你爬了一千条商品信息最后往往就是一句 rows.append([...]) 然后 writer.writerows(rows) 收工。今天案例二、案例三练的功夫到了爬虫场景几乎是直接平移使用。再说数据分析。数据分析的第一步永远是读数据pandas 是一个强大的数据处理库它的 read_csv、read_json 底层就是在做你今天做的事——只不过包了一层更好用的接口。如果你连文件编码、格式、路径这些底层概念都没搞清楚用 pandas 时遇到读不出来的报错会完全不知道从哪里排查。而有了今天的基础你会知道问题大概率出在编码或路径上排查思路和定位效率完全不同。5.2 学完今天的内容下一步怎么发展如果你今天的内容都照着敲完了我给你几个具体的进阶建议。第一尝试把案例二和案例三结合用 config.json 存输入文件名、关键词、输出文件路径这些参数然后写一个通用化的数据处理脚本。这基本就是一个“准生产级”的小工具模式了你能体会到配置和代码分离带来的好处。第二练一练用 pathlib 模块做路径处理。它是 Python 3.4 之后引入的新路径库整体 API 设计比 os.path 更现代操作文件路径的代码写起来也更直观。如果你想往专业方向走pathlib 迟早要学。第三等你的文件处理练熟了可以考虑接触一下正则表达式。它能帮你从日志、网页、文本里更精准地提取信息和文件操作配合使用你写出来的脚本会瞬间上一个档次。第四如果对处理超大文件感兴趣可以了解一下协程和分批处理的思想这也是 Python 处理高并发、大数据时的核心思路之一。但别急那都是后面的事今天把文件读写练扎实就是最值得的一步。最后再分享一个我的带教心得文件操作这一块我带了这么多新人发现一个很普遍的现象——很多人把 with open 当成一个模板死记硬背代码能跑但是说不清原理。等到真正做项目时90% 的报错恰恰都出在这条最简单的语句上不是路径错了就是编码乱了。所以今天文章中四个案例你最好每一行都亲手敲一遍尤其是 CSV 和 JSON 那两个。等你熟练到闭着眼都能写出“读配置 → 处理数据 → 写结果”这套流程后面学爬虫、做数据分析你会发现到处都是熟悉的味道那种感觉真的很爽。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。