当前位置: 首页 > news >正文

【Python系列课程】Python文件操作:从路径处理到with语句

📊 阅读时长:20分钟 | 关键词:Python文件操作、open()、读写模式、with语句、os模块、路径处理

引言:和计算机关打交道的唯一方式

前面讲的都是"计算"——加减乘除、列表操作、函数调用。但程序真正强大之处,在于能和文件系统打交道:

  • 读取配置文件(.ini.json.yaml
  • 处理用户上传的文件(.csv.xlsx、图片)
  • 生成报表输出到本地(.txt.pdf.docx
  • 日志系统(.log文件的读写)

Python 的文件操作 API 设计得非常优雅,学完这篇,你基本上能应付 90% 的文件处理任务。


一、路径操作:文件在哪?

在操作文件之前,你得先搞清楚文件在哪——这就是路径做的事。

1.1 绝对路径 vs 相对路径
类型说明示例(Windows)示例(macOS/Linux)
绝对路径从根目录开始的完整路径D:\PythonFiles\p01.py/home/user/code/main.py
相对路径相对于当前工作目录的路径.\data\input.txt./data/input.txt

获取当前工作目录

importos cwd=os.getcwd()print(cwd)# 输出当前工作目录

相对路径的特殊符号

  • .→ 当前目录
  • ..→ 上一级目录
os.getcwd()# D:\PythonFilesos.path.join('.','data','input.txt')# .\data\input.txtos.path.join('..','main.py')# ..\main.py
1.2os.path常用方法速查
importos path=r'D:\PythonFiles\data\input.txt'os.path.basename(path)# 'input.txt' → 最后一级(文件名)os.path.dirname(path)# 'D:\PythonFiles\data' → 目录部分os.path.split(path)# ('D:\...\data', 'input.txt')os.path.splitext(path)# ('D:\...\input', '.txt') → 拆分扩展名os.path.exists(path)# False(不存在)os.path.isfile(path)# Falseos.path.isdir(path)# False

📸[图1:os.path各方法解析效果对比图]
建议配图:一张表中列出同一个路径字符串,分别用basename/initname/split/splitext处理后得到的返回值,直观展示每个方法"切"出来的部分。

1.3os.path.join():智能拼接路径(跨平台必备)

永远不要用字符串拼接路径!不同操作系统的路径分隔符不同(Windows 用\,macOS/Linux 用/)。os.path.join()会根据当前操作系统自动选择正确的分隔符。

importos# ❌ 错误写法(不跨平台)path='data'+'\\'+'input.txt'# 在 Mac 上会出错# ✅ 正确写法path=os.path.join('data','input.txt')print(path)# Windows → data\input.txt# macOS/Linux → data/input.txt
1.4 创建目录:os.makedirs()
importos# 创建单层目录os.mkdir('new_folder')# 递归创建多层目录(自动创建中间目录)os.makedirs('./dir1/dir2/dir3',exist_ok=True)# exist_ok=True:目录已存在时不报错

二、open():打开文件的万能钥匙

2.1 基本语法
file=open(file,mode='r',encoding=None)
参数说明
file文件路径(绝对或相对)
mode打开模式,默认'r'(只读)
encoding文本文件编码,建议显式指定'utf-8'

返回一个文件对象(迭代器对象),可以用for循环逐行读取。

2.2 文件打开模式详解
模式说明文件不存在时文件已存在时
'r'只读报错FileNotFoundError正常打开,指针在开头
'w'只写(覆盖)创建新文件清空原内容再写入
'a'只写(追加)创建新文件指针在末尾,追加写入
'x'独占创建创建新文件报错FileExistsError
'b'二进制模式需配合r/w/a使用
'+'读写模式需配合r/w/a使用

组合模式示例

open('file.txt','rb')# 二进制只读(如读取图片)open('file.txt','wb')# 二进制只写open('file.txt','r+')# 读写,指针在开头open('file.txt','w+')# 读写,清空后写入open('file.txt','a+')# 读写,指针在末尾
2.3 文本文件 vs 二进制文件
类型编码示例文件打开模式
文本文件需要指定encoding.txt.py.json.md'r'/'w'/'a'(默认)
二进制文件无编码,直接读写字节.png.mp3.exe.zip'rb'/'wb'/'ab'

三、文件对象的常用方法

3.1 读取内容
withopen('./exam.txt','r',encoding='utf-8')asf:# 方式1:next() 读取一行(文件是迭代器)print(next(f))# 方式2:for 循环逐行读取(最常用,内存友好)forlineinf:print(line,end='')# end='' 去掉多余的换行# 方式3:read(size) 读取指定字符数f.seek(0)# 指针回到开头content=f.read(5)# 读取前5个字符print(content)# 方式4:read() 读取全部f.seek(0)all_content=f.read()print(all_content)# 方式5:readlines() 读取全部行到列表f.seek(0)lines=f.readlines()print(lines)# ['line1\n', 'line2\n', ...]

📸[图2:文件指针移动示意图]
建议配图:一个横向的文本流,标注指针位置(seek),展示 read(5) 从指针处读取5个字符后指针移动到第6个字符位置。

3.2 写入内容
withopen('./exam.txt','w',encoding='utf-8')asf:# write(s):写入字符串,返回写入的字符数num=f.write('Hello World\n')print(f'写入了{num}个字符')# writelines(lines):写入字符串列表(不会自动加换行!)lines=['Line 1\n','Line 2\n','Line 3\n']f.writelines(lines)

⚠️ 注意writelines()不会自动添加换行符,需要自己加\n

3.3 移动文件指针:seek(offset)
withopen('./exam.txt','r+',encoding='utf-8')asf:f.write('Hello')f.seek(0)# 指针回到开头print(f.read())# 从头开始读取
3.4 刷新缓冲区:flush()

写入文件时,Python 会先把内容放到缓冲区,等缓冲区满了或文件关闭时才真正写入磁盘。flush()可以强制立即写入。

importtime f=open('./test.txt','a',encoding='utf-8')f.write('123456789\n')f.flush()# 立即写入磁盘(不等文件关闭)time.sleep(5)# 这5秒内文件里已经有内容了f.close()

四、with语句:最优雅的文件操作方式

4.1 为什么要用with

传统写法需要手动关闭文件,如果中间发生异常,close()可能执行不到:

# ❌ 不推荐的写法f=open('./test.txt','w',encoding='utf-8')f.write('hello world')# 如果这里发生异常,close() 不会执行 → 文件损坏风险f.close()

with语句的好处:无论是否发生异常,退出with块时自动执行close()

# ✅ 推荐写法withopen('./test.txt','w',encoding='utf-8')asf:f.write('hello world')# 退出 with 块时,自动调用 f.close()

等价于:

f=open('./test.txt','w',encoding='utf-8')try:f.write('hello world')finally:f.close()# 无论如何都会执行
4.2with+try/except/finally组合
try:withopen('./test.txt','r',encoding='utf-8')asf:content=f.read()print(content)exceptFileNotFoundError:print('文件不存在!')exceptUnicodeDecodeError:print('文件编码不是 UTF-8!')finally:print('文件操作结束(自动关闭)')

五、实战:几个常用文件操作场景

5.1 复制文件
defcopy_file(src,dst):"""复制文件(支持文本和二进制)"""withopen(src,'rb')asfsrc:withopen(dst,'wb')asfdst:whileTrue:chunk=fsrc.read(4096)# 每次读 4KBifnotchunk:breakfdst.write(chunk)print(f'已复制:{src}{dst}')copy_file('./source.jpg','./backup/copy.jpg')
5.2 逐行处理日志文件(内存友好)
# 处理大文件时,绝对不能用 read() 一次性读入内存!# 用 for 循环逐行读取,每次只占用一行的内存error_count=0withopen('./app.log','r',encoding='utf-8')asf:forlineinf:# 逐行迭代,内存占用极低if'ERROR'inline:error_count+=1print(f'发现错误:{line.strip()}')print(f'共发现{error_count}处错误')
5.3 CSV 文件读写(数据分析必备)
importcsv# 读取 CSVwithopen('./data.csv','r',encoding='utf-8')asf:reader=csv.reader(f)header=next(reader)# 跳过表头print(f'表头:{header}')forrowinreader:print(row)# 写入 CSVwithopen('./output.csv','w',newline='',encoding='utf-8')asf:writer=csv.writer(f)writer.writerow(['姓名','年龄','城市'])# 写表头writer.writerows([['小明',25,'北京'],['小红',23,'上海'],])

六、动手练习

练习 1:统计文件行数

defcount_lines(filepath):"""统计文件行数"""withopen(filepath,'r',encoding='utf-8')asf:returnsum(1for_inf)# 逐行迭代计数print(count_lines('./exam.txt'))

练习 2:查找包含关键词的行

defgrep(filepath,keyword):"""查找包含关键词的所有行"""withopen(filepath,'r',encoding='utf-8')asf:fori,lineinenumerate(f,1):ifkeywordinline:print(f'第{i}行:{line.strip()}')grep('./app.log','ERROR')

练习 3:批量重命名文件

importosdefbatch_rename(folder,old_ext,new_ext):"""批量修改文件扩展名"""forfilenameinos.listdir(folder):iffilename.endswith(old_ext):old_path=os.path.join(folder,filename)new_filename=filename.replace(old_ext,new_ext)new_path=os.path.join(folder,new_filename)os.rename(old_path,new_path)print(f'{filename}{new_filename}')batch_rename('./images','.jpeg','.jpg')

小结

知识点一句话总结
路径操作os.path.join()拼接路径,跨平台
open()打开文件,返回文件对象;指定modeencoding
读写模式'r'只读 /'w'覆盖 /'a'追加 /'b'二进制
读取方法read()全读 /readline()读一行 /for line in f逐行(推荐)
写入方法write()写字符串 /writelines()写列表
with语句自动关闭文件,异常处理更安全,必须用
大文件处理for line in f逐行读取,不要用read()

📸[图3:文件操作流程全景图]
建议配图:一张完整的流程图,从open()打开文件 → 选择读写模式 → 调用 read/write 方法 → 关闭文件(close 或 with 自动关闭),并在底部标注"文本模式 vs 二进制模式"的区别。


本文是「Python从入门到数据分析」系列的第 13 篇,共 24 篇。关注我,不错过后续更新。

http://www.rkmt.cn/news/1442680.html

相关文章:

  • 3大优势揭秘:这款开源工具如何成为华硕笔记本臃肿软件的完美替代方案
  • 基于ESP32与LoRa的土壤监测网关:从硬件连接到代码实现的完整指南
  • 别再死记硬背了!用MATLAB和Keras手把手拆解1DCNN,搞懂时序数据处理的底层逻辑
  • Sora 2虚拟会议背景如何重构远程协作体验:2024年实测8大行业落地数据与性能基准报告
  • 3步破解:REPENTOGON深度架构解析与高级配置指南
  • 2026包头母婴除甲醛公司TOP5深度测评:5大优选甲醛检测治理品牌 - 诚信金利回收
  • 如何快速掌握网页资源嗅探:猫抓插件的完整使用指南
  • 在Windows上安装Android应用的终极指南:APK Installer完全免费解决方案
  • Sora 2生成的沙发会“塌陷”?深度解析家具结构物理约束缺失问题及Blender+NeRF联合修复方案
  • 2026年度国产品牌在线DO仪源头厂家权威推荐榜:十大品牌综合实力深度测评与选型指南 - 仪表品牌榜
  • 别再恐慌了:一份给工程师的AI漏洞发现与修复务实指南
  • 终极指南:Windows版微信QQ消息防撤回完整解决方案
  • Firefox下载Keil工具时OCSP验证失败的解决方案
  • 【Sora 2医学动画制作实战指南】:20年影像科AI工程师首度公开5大不可外传的解剖级帧控技巧
  • THP--CSK 基于linux服务器的内网域环境渗透
  • 轮换对称
  • 亲测:2026年5月台州华声汽车音响改装专业汽车音响实改 - GrowthUME
  • 5分钟掌握Illustrator批量替换:ReplaceItems.jsx完整使用指南
  • 辽源家庭教育指导师报名入口、流程、哪家机构好:中山优才教育 - 最新教育培训热点
  • ComfyUI-MingNodes:5大核心技术解决AI图像处理的色彩与光影难题
  • 阳泉家庭教育指导师报名入口怎么找?官方授权机构推荐:中山优才教育 - 当下教育培训干货
  • POI 搜索新方向:向量重排打通语义与空间的闭环
  • 渭南白蚁消杀防治|金盾虫控 青蚁卫士:深耕 15 年本土知名品牌,专业虫害防控守护千家万户住宅安全 - 卓一科技
  • 2026北海母婴除甲醛公司TOP5深度测评:5大优选甲醛检测治理品牌 - 诚信金利回收
  • 明日方舟素材宝库:解锁10000+游戏资源的开发者解决方案
  • 昆山城西空调维修服务机构排行及选型参考 - 互联网科技品牌测评
  • 消防安全科普展厅设备【火灾隐患查找系统】
  • 新手店长必看,2026年开发收银系统用什么软件? - FaiscoJeff
  • 手把手教你用示波器完成SFP+光模块一致性测试(附PRBS码型详解与避坑指南)
  • 2026年周边美食推荐:这5家最靠谱,吃过都说好