python文件读写造作最佳实践——with语句管理文件资源
off999 2025-05-11 00:12 23 浏览 0 评论
with 语句(上下文管理器)是 Python 中处理文件操作的首选方式,它能自动管理资源,确保文件正确关闭,即使发生异常也是如此。下面详细介绍如何正确使用 with 进行文件读写操作。
一、为什么使用with语句?
传统文件操作方式的问题:
file = open('example.txt', 'r')
content = file.read()
file.close() # 必须显式关闭,否则可能导致资源泄漏
潜在问题:
- 忘记调用 close() 方法
- 代码抛出异常导致 close() 未被执行
- 代码复杂时难以确保所有路径都关闭文件
with 语句的优势:
- 自动资源管理:离开 with 块时自动关闭文件
- 异常安全:即使发生异常也会确保文件关闭
- 代码简洁:减少样板代码
- 可读性强:明确显示文件的作用域
二、基本语法
1. 读取文件
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read()
# 在此块内操作文件
# 离开with块后文件自动关闭
print(content) # 文件已关闭,但内容已读取到变量
2. 写入文件
with open('output.txt', 'w', encoding='utf-8') as file:
file.write('Hello, World!\n')
file.write('这是第二行\n')
# 文件自动关闭,内容已写入磁盘
3. 追加内容
with open('output.txt', 'a', encoding='utf-8') as file:
file.write('这是追加的内容\n')
三、高级用法
1. 同时处理多个文件
with open('source.txt', 'r') as src, open('destination.txt', 'w') as dst:
content = src.read()
dst.write(content)
# 两个文件都会自动关闭
2. 二进制文件操作
# 复制图片文件
with open('input.jpg', 'rb') as src, open('output.jpg', 'wb') as dst:
dst.write(src.read())
3. 异常处理
try:
with open('config.json', 'r') as file:
data = json.load(file)
except FileNotFoundError:
print("配置文件不存在")
except json.JSONDecodeError:
print("配置文件格式错误")
except IOError as e:
print(f"文件操作错误: {e}")
4. 使用with和iter高效读取大文件
with open('large_file.log', 'r') as file:
for line in iter(file.readline, ''): # 逐行读取,内存高效
process_line(line)
四、with语句的工作原理
with 语句实际上使用了上下文管理器协议,open() 返回的文件对象实现了这个协议:
- 进入 with 块时调用 __enter__() 方法
- 离开 with 块时调用 __exit__() 方法(即使发生异常)
- __exit__() 方法中包含了文件关闭的逻辑
等效的传统写法:
file = open('example.txt', 'r')
try:
content = file.read()
finally:
file.close()
五、实际应用示例
示例1:配置文件读取
import json
def load_config(config_path):
try:
with open(config_path, 'r', encoding='utf-8') as file:
return json.load(file)
except (FileNotFoundError, json.JSONDecodeError) as e:
print(f"加载配置失败: {e}")
return {}
示例2:日志文件处理
def process_log_file(log_path):
with open(log_path, 'r') as log_file:
for line in log_file:
if 'ERROR' in line:
send_alert(line.strip())
def send_alert(error_msg):
with open('alerts.log', 'a') as alert_file:
alert_file.write(f"{datetime.now()}: {error_msg}\n")
示例3:CSV 数据处理
import csv
def process_csv(input_path, output_path):
with open(input_path, 'r') as infile, open(output_path, 'w', newline='') as outfile:
reader = csv.DictReader(infile)
writer = csv.DictWriter(outfile, fieldnames=reader.fieldnames)
writer.writeheader()
for row in reader:
if is_valid(row):
writer.writerow(process_row(row))
六、注意事项
- 编码问题:始终明确指定文件编码(推荐 utf-8)
with open('file.txt', 'r', encoding='utf-8') as f:
- 缓冲设置:处理大量数据时可调整缓冲区大小
with open('large.data', 'wb', buffering=1024*1024) as f: # 1MB缓冲
- 文件位置:with 块结束后文件指针位置
with open('file.txt', 'r+') as f:
content = f.read() # 读取后指针在文件末尾
f.seek(0) # 需要重置指针才能再次读取或写入
- 不要重复使用文件对象:
with open('file.txt') as f:
data1 = f.read() # 第一次读取
data2 = f.read() # 第二次读取将得到空字符串!
七、性能考虑
对于性能关键代码:
- 大文件使用逐行或分块读取
with open('huge.log') as f:
for line in f: # 内存高效
process(line)
- 多次小写入可考虑先收集数据再一次性写入
data = []
for item in items:
data.append(format_item(item))
with open('output.txt', 'w') as f:
f.writelines(data)
总结
- 总是使用 with 语句处理文件操作
- 明确指定文件编码(特别是文本文件)
- 根据需要选择合适的读写模式
- 大文件使用迭代方式处理
- 注意文件指针位置
- 考虑使用 pathlib 进行路径操作(Python 3.4+)
相关推荐
- Kubernetes 核心概念全景图:Pod、Node、Cluster、Control Plane 等
-
想真正读懂Kubernetes的底层运作,你必须理解它的“权力架构”。Pod是什么?Node是什么?ControlPlane又是做什么的?它们之间有什么关系?怎么协同工作?本篇带你构建一个...
- Helm 实战:用 Helm 部署一个 Nginx 应用
-
这一篇,我们将动手实战:用Helm从零部署一个Nginx应用,并掌握HelmChart的结构和参数化技巧。一、准备环境在开始之前,你需要确保环境中具备以下工具:已部署的Kubernet...
- 从零开始:如何在 Linux 上搭建 Nginx + Node.js 高性能 Web 服务
-
在现代互联网服务架构中,Nginx+Node.js已成为轻量级、高性能网站的首选组合。本文将带你从零开始,一步步搭建一个高并发、高可用的Web服务平台,让新手也能轻松掌握生产级部署思路。一、...
- NetBox 最新版 4.4.1 完整安装指南
-
NetBox最新版4.4.1完整安装指南(修正版)by大牛蛙1.系统准备#关闭SELinux和防火墙(仅测试环境)systemctldisable--nowfirewalldse...
- Termux 安装 linux 宝塔面板,搭建 Nginx+PHP+Mysql web 网站环境
-
Termux安装linux宝塔面板,搭建Nginx+PHP+Mysqlweb服务环境,解决启动故障奶妈级教程1.到宝塔面板官网:https://www.bt.cn/new/download...
- OpenEuler系统安装Nginx安装配置_openwrt安装nginx
-
NginxWEB安装时可以指定很多的模块,默认需要安装Rewrite模块,也即是需要系统有PCRE库,安装Pcre支持Rewrite功能。如下为安装NginxWEB服务器方法:源码的路径,而不是编...
- 多级缓存架构实战:从OpenResty到Redis,打造毫秒级响应系统
-
在传统的Web架构中,当用户发起请求时,应用通常会直接查询数据库。这种模式在低并发场景下尚可工作,但当流量激增时,数据库很容易成为性能瓶颈。多级缓存通过在数据路径的不同层级设置缓存,可以显著降低数据库...
- 如何使用 Nginx 缓存提高网站性能 ?
-
快速加载的站点提供了更好的用户体验并且可以拥有更高的搜索引擎排名。通过Nginx缓存提高你的网站性能是一个有效的方法。Nginx是一个流行的开源web服务器,也可以作为web服务器反向代...
- 如何构建企业级Docker Registry Server
-
很多人问我,虚拟机镜像和docker镜像的区别是什么?其实区别非常明显,我们可以通过阅读Dockerfile文件就可以知道这个镜像都做了哪些操作,能提供什么服务;但通过虚拟机镜像,你能一眼看出来虚拟机...
- 如何解决局域网SSL证书问题?使用mkcert证书生成工具轻松搞定
-
“局域网里弹出‘不安全’红锁,老板就在身后盯着演示,那一刻只想原地消失。”别笑,九成前端都经历过。自签证书被Chrome标红,客户以为网站被黑,其实只是缺一张被信任的证。mkcert把这事从半小时缩到...
- Docker 安全与权限控制:别让你的容器变成“漏洞盒子”
-
在享受容器带来的轻量与灵活的同时,我们也必须面对一个现实问题:安全隐患。容器并不是天然安全,错误配置甚至可能让攻击者“越狱”入侵主机!本篇将带你从多个层面强化Docker的安全防护,构建真正可放心...
- Kubernetes生产级管理指南(2025版)
-
在云原生技术持续演进的2025年,Kubernetes已成为企业数字化转型的核心引擎。然而,生产环境中的集群管理仍面临基础设施配置、安全漏洞、运维复杂度攀升等挑战。本文将结合最新行业实践,从基础设施即...
- 云原生工程师日常使用最多的工具和100条高频命令
-
在云原生时代,工程师不仅要熟悉容器化、编排和服务网格,还要掌握大量工具和命令来进行日常运维与开发。本文将从工具篇和命令篇两个角度,详细介绍云原生工程师每天都会用到的核心技能。一、云原生工程师常...
- 用 Jenkins 实现自动化 CI/CD_jenkins api自动执行
-
场景设定(可替换为你的技术栈)语言:Node.js(示例简单,任何语言思路一致)制品:Docker镜像(推送到DockerHub/Harbor)运行环境:Kubernetes(staging...
- 5款好用开源云笔记虚拟主机部署项目推荐
-
在个人数据管理与协同办公场景中,开源云笔记项目凭借可自主部署、数据可控的优势,成为众多用户的首选。以下推荐5款适配虚拟主机部署、功能完善的开源项目,附核心特性与部署要点,助力快速搭建专属云笔记系统。...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Kubernetes 核心概念全景图:Pod、Node、Cluster、Control Plane 等
- Helm 实战:用 Helm 部署一个 Nginx 应用
- 从零开始:如何在 Linux 上搭建 Nginx + Node.js 高性能 Web 服务
- NetBox 最新版 4.4.1 完整安装指南
- Termux 安装 linux 宝塔面板,搭建 Nginx+PHP+Mysql web 网站环境
- OpenEuler系统安装Nginx安装配置_openwrt安装nginx
- 多级缓存架构实战:从OpenResty到Redis,打造毫秒级响应系统
- 如何使用 Nginx 缓存提高网站性能 ?
- 如何构建企业级Docker Registry Server
- 如何解决局域网SSL证书问题?使用mkcert证书生成工具轻松搞定
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)