Python 文件操作魔法手册:open函数的终极艺术
liuian 2025-04-11 00:59 94 浏览
Python 文件操作魔法手册:open 函数的终极艺术
对话实录
小白:(崩溃)我写了open("data.txt"),为什么报错?
专家:(掏出魔法书)文件操作要小心,模式、编码都要注意!
open 函数基础三连击
1. 基本用法
# 读取文件
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
# 写入文件
with open("output.txt", "w") as f:
f.write("Hello World!")
专家提醒:一定要用with语句,它能在代码块结束时自动关闭文件,防止资源泄露。想象一下,你打开一扇门进入房间,离开时却忘记关门,这可能会带来安全隐患。在文件操作中,忘记关闭文件就如同忘记关门,可能导致数据丢失或系统资源被占用。使用with语句就像是有一个贴心的助手,在你离开房间时自动帮你关门。
2 open函数参数介绍
open函数的参数
open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)
1)file:传入不带路径的字符串(文本文件/二进制文件)或者带有绝对路径或者相对路径的文件。如果传入的文件不存在,默认会创建文件。
如果传入的文件不合要求,会报错如下:
2)mode:指明文件打开模式的可选字符串。默认为‘r’表示以文本模式读取。
字符 | 含意 |
'r' | 只读取(默认);文件必须存在,否则会报错。 |
'w' | 只写入,是覆盖式写入(比如第一次写入后,再次打开以w方式写入会覆盖原内容。) |
'x' | 排它性创建,如果文件已存在则失败。如果文件不存在则创建,模式为写入,与'w'类似。 |
'a' | 只写入,再次打开文件并不会覆盖,而是在末尾追加写入。 |
'b' | 表示二进制模式读取和写入,不能单独使用,须与'r','w','a','x'配合使用。 比如打开一张图片文件,如果用文本模式打开,看到的将是一堆乱码,因为图片数据是二进制格式,需要用二进制模式正确读取。 |
't' | 文本模式(默认),与'r','w','a','x'配合使用。 比如'r'与'rt'同义,一般直接使用'r'。 |
'+' | 打开用于更新(读取与写入),不能单独使用,须与'r','w','a','x'配合使用。 |
以上模式结合使用:
a. 只读取:'r',’rb’
b. 只写入:'w',’wb’,’a’,’ab’,'x','xb'
c. 读取和写入:'r+',’r+b’,'w+',’w+b’,’a+’,’a+b’,’x+’,’x+b’
- 'r+':以读写模式打开文件,文件指针会放在文件的开头。
- 'w+':以读写模式打开文件,原文件内容会被删除。(慎用)
- 'a+':以读写模式打开文件用于追加,文件指针会放在文件的末尾(表现为以a+模式打开文件直接读取内容,读取的内容为空)。
在读取和写入模式下我们可以使用seek()方法来移动文件指针到指定位置,以便在文件的任意位置进行读写操作。
3)buffering:参数可选,表示设置缓冲策略,默认为None。0表示无缓冲(仅适用于二进制模式),大于0表示缓冲区的大小(以字节为单位)。
4)encoding:参数可选,默认为系统默认编码(在Python 3中通常是UTF-8);在文本模式下可以指定编码,在二进制模式下不需要指定编码。
5)errors:参数可选,指定编码和解码错误的处理方式。默认为None,跟值'strict'效果一样,表示严格处理错误,其他值如'ignore'用于忽略错误、'replace'替换一些错误标记等。
5)newline:参数可选,用于控制文件读取和写入时行的结束符。默认为None,表示使用系统默认的行结束符,比如'\r\n','\n'。在文本模式下读取文件时,默认把平台特定的行结束符(Unix 上为 \n, Windows 上为 \r\n)转换为 \n。在文本模式下写入数据时,默认把 \n 转换回平台特定结束符。
6)closefd:参数可选,closefd默认为True表示当文件对象被关闭时,同时关闭文件描述符,防止资源泄漏。当closefd为False指当文件对象被关闭时,不关闭文件描述符。当file参数传入的是文本文件时,该参数必须为Ture,否则会报错。
3 常用方法介绍
1)读取方法
- read(size=-1):从文件中读取并返回指定数量的字符或者字节,如果不指定size则读取并返回文件的全部内容。
- readline(size=-1):从文件中读取并返回一行(直到换行符 \n),或返回指定数量的字节。
- readlines(hint=-1):读取所有行并返回列表,其中每一行都是一个字符串。如果指定了 hint,则读取指定数量的字符或者字节。
2)写入方法
- write(str):将字符串或字节写入文件,只写入一行,并且不会在末尾添加换行符,需要自己添加。
- writelines(lines):向文件写入一个字符串或者字节列表,可写入多行,并且不会在末尾添加换行符,需要自己添加。
3)移动文件对象指针位置
- seek(offset, whence=0):移动文件读取指针到指定位置。offset 是指从 whence 指定的位置开始计算的字符或者字节数。whence 的值为 0(文件开头,默认值)、1(当前位置)或 2(文件末尾)。
- tell():返回文件当前的指针位置。
4)关闭文件对象
close():关闭文件对象。
其他方法
flush():将缓冲区的内容写入文件,但不关闭文件。
fileno():返回文件的描述符(一个小的非负整数)。
isatty():如果文件是一个与终端设备(tty)相关联的,则返回 True,否则返回 False.
readable()、writable()、seekable():分别用于检查文件是否可读、可写、以及是否支持 seek() 操作。
truncate(size=None):截断文件到指定大小。如果 size 未指定,则截断文件到当前位置。如果当前位置大于文件大小,则文件将被扩展,并且扩展部分的内容将用零字节填充。
4 常用属性介绍
- name 属性:返回打开文件的名称。
- closed 属性:返回一个布尔值,指示文件是否已关闭。当文件被成功打开时,closed 属性为 False。一旦文件被关闭,closed属性为True。
- mode属性:返回open函数传入的mode值。
- encoding属性:返回open函数使用的编码。
- buffer属性:返回open函数的buffer配置。
- errors属性:返回open函数的errors配置。
六大实战案例
案例 1:逐行读取大文件
# 错误示范
with open("big.txt") as f:
lines = f.readlines() # 内存爆炸!
这种方式会一次性将整个文件读入内存,如果文件非常大,可能会耗尽系统内存,导致程序崩溃。
# 正确做法
with open("big.txt") as f:
for line in f: # 逐行读取
process(line)
逐行读取大文件,每次只在内存中处理一行数据,大大降低了内存压力。
案例 2:CSV 文件处理
import csv
with open("data.csv", newline="") as f:
reader = csv.reader(f)
for row in reader:
print(row)
CSV(Comma - Separated Values)文件常用于存储表格数据,如数据库导出的数据。使用csv模块可以方便地读取和写入 CSV 文件。在这个例子中,newline=""参数用于避免在读取 CSV 文件时出现额外的空行,确保数据读取的准确性。
案例 3:JSON 文件读写
import json
# 读取json文件内容为python对象
with open("data.json") as f:
data = json.load(f)
# 将python对象写入json文件
with open("output.json", "w") as f:
json.dump(data, f, indent=2)
JSON(JavaScript Object Notation)文件常用于存储结构化数据,在 Web开发和数据交换中广泛应用。json.load(f)用于将文件中的JSON 数据解析为Python 对象,json.dump(data, f, indent = 2)则将 Python 对象转换为JSON 格式并写入文件,indent = 2参数使生成的JSON文件更加美观易读,数据层次结构一目了然。
案例 4:XML 文件解析
import xml.etree.ElementTree as ET
tree = ET.parse("data.xml")
root = tree.getroot()
for child in root:
print(child.tag, child.attrib)
XML(eXtensible Markup Language)也是一种常用的结构化数据格式,常用于配置文件和数据交换。通过xml.etree.ElementTree模块可以轻松解析 XML 文件。在这个例子中,我们使用ET.parse方法读取 XML 文件,然后获取根元素,并遍历根元素的子元素,打印出每个子元素的标签和属性。
案例 5:日志文件处理
import logging
logging.basicConfig(filename='app.log', level=logging.INFO)
logging.info('程序开始运行')
try:
result = 1 / 0
except ZeroDivisionError as e:
logging.error(f'发生错误: {e}')
logging.info('程序结束运行')
在开发应用程序时,记录日志是非常重要的。它可以帮助我们追踪程序的运行状态,排查错误。通过logging模块,我们可以方便地将日志信息写入文件。在这个例子中,我们设置日志级别为INFO,记录程序的开始和结束运行信息,并在发生ZeroDivisionError错误时记录错误信息到app.log文件中。
案例 6:图片文件处理(简单的图片格式转换)
from PIL import Image
try:
img = Image.open('input.jpg')
img.save('output.png', 'PNG')
except Exception as e:
print(f'处理图片时发生错误: {e}')
使用 Python 的PIL(Python Imaging Library)库可以对图片进行各种处理,如格式转换、裁剪、调整大小等。在这个例子中,我们将一张 JPEG 格式的图片转换为 PNG 格式。Image.open方法用于打开图片文件,img.save方法用于将图片保存为指定格式。
四大血泪陷阱
忘记关闭文件
# 错误示范
f = open("data.txt")
content = f.read()
# 忘记f.close()
在这种情况下,文件在读取操作完成后没有被关闭,可能会导致资源泄露。如果程序中多次出现这种情况,可能会耗尽系统的文件描述符资源,导致程序无法再打开新的文件。
# 正确做法
with open("data.txt") as f:
content = f.read()
with语句会自动管理文件的生命周期,在代码块结束时关闭文件,确保资源得到正确释放。
编码问题
# 错误示范
with open("data.txt") as f: # 默认编码可能出错
content = f.read()
不同的操作系统和文本编辑器可能使用不同的默认编码。如果在打开文件时不指定编码,可能会导致读取文件时出现乱码或UnicodeDecodeError错误。例如,在 Windows 系统中,默认编码可能是cp936,而在处理包含非 ASCII 字符的文件时,可能会出现编码不匹配的问题。
# 正确做法
with open("data.txt", encoding="utf-8") as f:
content = f.read()
显式指定编码为utf - 8,这是一种通用的编码格式,能够处理各种语言的字符,避免编码问题。
路径问题
# 错误示范
open("data.txt") # 相对路径可能出错
使用相对路径时,文件的实际位置取决于当前工作目录。如果在不同的环境中运行程序,或者当前工作目录被改变,可能会导致找不到文件。比如,在一个脚本中使用相对路径open("data.txt"),在脚本所在目录运行程序时可以正常找到文件,但如果在其他目录运行,就可能找不到该文件。
# 正确做法
from pathlib import Path
file = Path(__file__).parent / "data.txt"
with open(file) as f:
content = f.read()
使用Pathlib模块来处理路径,它提供了一种跨平台的路径操作方式。Path(__file__).parent获取当前脚本所在的目录,然后通过/运算符拼接文件名,确保无论在何种环境下都能正确定位文件。
文件模式误用
# 错误示范
with open("data.txt", "w") as f:
data = f.read() # 写入模式下不能读取
在这种情况下,以w(写入)模式打开文件后,尝试读取文件内容,会导致io.UnsupportedOperation错误,因为w模式只允许写入操作,不允许读取。
# 正确做法
with open("data.txt", "r+") as f:
data = f.read()
f.write("追加的内容")
如果需要对文件进行读写操作,应使用合适的模式,如r+模式,它允许在读取文件的同时进行写入操作。
专家工具箱
1. 二进制文件操作
# 读取图片
with open("image.png", "rb") as f:
data = f.read()
# 写入二进制
with open("output.bin", "wb") as f:
f.write(b"\x00\x01\x02")
二进制文件操作在处理图片、音频、视频等非文本文件时非常重要。在读取图片时,使用rb(二进制读取)模式,确保文件内容被正确读取。写入二进制数据时,使用wb(二进制写入)模式,数据以字节形式写入文件。例如,b"\x00\x01\x02"表示写入三个字节的数据,每个字节的值分别为 0、1、2。
2. 文件指针操作
with open("data.txt") as f:
f.seek(10) # 移动到第10字节
print(f.read(5)) # 读取5个字符
文件指针用于指示当前文件读取或写入的位置。f.seek(offset, whence)方法用于移动文件指针,offset表示偏移量,whence表示参考位置,0 表示文件开头,1 表示当前位置,2 表示文件末尾。在这个例子中,f.seek(10)将文件指针移动到第 10 个字节的位置,然后f.read(5)从该位置读取 5 个字符。通过灵活操作文件指针,可以实现对文件内容的随机访问,比如读取文件中间某一段特定的数据。
3. 临时文件
from tempfile import TemporaryFile
with TemporaryFile("w+") as f:
f.write("临时数据")
f.seek(0)
print(f.read())
临时文件在程序运行过程中用于临时存储数据,当程序结束时,临时文件会自动被删除。TemporaryFile函数创建一个临时文件,w+模式表示可读写。在这个例子中,我们先写入一些临时数据,然后将文件指针移回开头,读取并打印这些数据。使用临时文件可以避免在磁盘上留下不必要的文件,同时保证数据的安全性,因为临时文件在程序结束后会自动消失,不用担心数据残留问题。
小白:(献上膝盖)原来文件操作这么讲究!
专家:(扶起小白)记住:文件操作要小心,资源泄露是大忌!
相关推荐
- 赶紧收藏!编程python基础知识,本文给你全部整理好了
-
想一起学习编程Python的同学,趁我粉丝少,可以留言、私信领编程资料~Python基础入门既然学习Python,那么至少得了解下这门编程语言,知道Python代码执行过程吧。Python的历...
- 创建绩效改进计划 (PIP) 的6个步骤
-
每个经理都必须与未能达到期望的员工抗衡,也许他们的表现下降了,他们被分配了新的任务并且无法处理它们,或者他们处理了自己的任务,但他们的行为对他人造成了破坏。许多公司转向警告系统,然后在这些情况下终止。...
- PI3K/AKT信号通路全解析:核心分子、上游激活与下游效应分子
-
PI3K/AKT/mTOR(PAM)信号通路是真核细胞中高度保守的信号转导网络,作用于促进细胞存活、生长和细胞周期进程。PAM轴上生长因子向转录因子的信号传导受到与其他多条信号通路的多重交叉相互作用的...
- 互联网公司要求签PIP,裁员连N+1都没了?
-
2021年刚画上句号,令无数互联网公司从业者闻风丧胆的绩效公布时间就到了,脉脉上已然炸了锅。阿里3.25、腾讯二星、百度四挡、美团绩效C,虽然名称五花八门,实际上都代表了差绩效。拿到差绩效,非但不能晋...
- Python自动化办公应用学习笔记3—— pip工具安装
-
3.1pip工具安装最常用且最高效的Python第三方库安装方式是采用pip工具安装。pip是Python包管理工具,提供了对Python包的查找、下载、安装、卸载的功能。pip是Python官方提...
- 单片机都是相通的_单片机是串行还是并行
-
作为一个七年的从业者,单片机对于我个人而言它是一种可编程的器件,现在长见到的电子产品中几乎都有单片机的身影,它们是以单片机为核心,根据不同的功能需求,搭建不同的电路,从8位的单片机到32位的单片机,甚...
- STM32F0单片机快速入门八 聊聊 Coolie DMA
-
1.苦力DMA世上本没有路,走的人多了,便成了路。世上本没有DMA,需要搬运的数据多了,便有了DMA。大多数同学应该没有在项目中用过这个东西,因为一般情况下也真不需要这个东西。在早期的单片机中...
- 放弃51单片机,直接学习STM32开发可能会面临的问题
-
学习51单片机并非仅仅是为了学习51本身,而是通过它学习一种方法,即如何仅仅依靠Datasheet和例程来学习一种新的芯片。51单片机相对较简单,是这个过程中最容易上手的选择,而AVR单片机则更为复杂...
- STM32串口通信基本原理_stm32串口原理图
-
通信接口背景知识设备之间通信的方式一般情况下,设备之间的通信方式可以分成并行通信和串行通信两种。并行与串行通信的区别如下表所示。串行通信的分类1、按照数据传送方向,分为:单工:数据传输只支持数据在一个...
- 单片机的程序有多大?_单片机的程序有多大内存
-
之前一直很奇怪一个问题,每次写好单片机程序之后,用烧录软件进行烧录时,能看到烧录文件也就是hex的文件大小:我用的单片机芯片是STM32F103C8T6,程序储存器(flash)只有64K。从...
- 解析STM32单片机定时器编码器模式及其应用场景
-
本文将对STM32单片机定时器编码器模式进行详细解析,包括介绍不同的编码器模式、各自的优缺点以及相同点和不同点的应用场景。通过阅读本文,读者将对STM32单片机定时器编码器模式有全面的了解。一、引言...
- 两STM32单片机串口通讯实验_两个32单片机间串口通信
-
一、实验思路连接两个STM32单片机的串口引脚,单片机A进行发送,单片机B进行接收。单片机B根据接收到单片机A的指令来点亮或熄灭板载LED灯,通过实验现象来验证是否通讯成功。二、实验器材两套STM32...
- 基于单片机的智能考勤机设计_基于51单片机的指纹考勤机
-
一、设计背景随着科技水平的不断发展,在这么一个信息化的时代,智能化信息处理已是提高效率、规范管理和客观审查的最有效途径。近几年来,国内很多公司都在加强对企业人员的管理,考勤作为企业的基础管理,是公司...
- STM32单片机详细教学(二):STM32系列单片机的介绍
-
大家好,今天给大家介绍STM32系列单片机,文章末尾附有本毕业设计的论文和源码的获取方式,可进群免费领取。前言STM32系列芯片是为要求高性能、低成本、低功耗的嵌入式应用设计的ARMCortexM...
- STM32单片机的 Hard-Fault 硬件错误问题追踪与分析
-
有过单片机开发经验的人应该都会遇到过硬件错误(Hard-Fault)的问题,对于这样的问题,有些问题比较容易查找,有些就查找起来很麻烦,甚至可能很久都找不到问题到底是出在哪里。特别是有时候出现一次,后...
- 一周热门
-
-
【验证码逆向专栏】vaptcha 手势验证码逆向分析
-
Python实现人事自动打卡,再也不会被批评
-
Psutil + Flask + Pyecharts + Bootstrap 开发动态可视化系统监控
-
一个解决支持HTML/CSS/JS网页转PDF(高质量)的终极解决方案
-
再见Swagger UI 国人开源了一款超好用的 API 文档生成框架,真香
-
网页转成pdf文件的经验分享 网页转成pdf文件的经验分享怎么弄
-
C++ std::vector 简介
-
飞牛OS入门安装遇到问题,如何解决?
-
系统C盘清理:微信PC端文件清理,扩大C盘可用空间步骤
-
10款高性能NAS丨双十一必看,轻松搞定虚拟机、Docker、软路由
-
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)