百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Python 文件操作魔法手册:open函数的终极艺术

liuian 2025-04-11 00:59 18 浏览

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+模式表示可读写。在这个例子中,我们先写入一些临时数据,然后将文件指针移回开头,读取并打印这些数据。使用临时文件可以避免在磁盘上留下不必要的文件,同时保证数据的安全性,因为临时文件在程序结束后会自动消失,不用担心数据残留问题。

小白:(献上膝盖)原来文件操作这么讲究!

专家:(扶起小白)记住:文件操作要小心,资源泄露是大忌!

相关推荐

GANs为何引爆机器学习?这篇基于TensorFlow的实例教程为你解惑!

「机器人圈导览」:生成对抗网络无疑是机器学习领域近三年来最火爆的研究领域,相关论文层出不求,各种领域的应用层出不穷。那么,GAN到底如何实践?本文编译自Medium,该文作者以一朵玫瑰花为例,详细阐...

高丽大学等机构联合发布StarGAN:可自定义表情和面部特征

原文来源:arXiv、GitHub作者:YunjeyChoi、MinjeChoi、MunyoungKim、Jung-WooHa、SungKim、JaegulChoo「雷克世界」编译:嗯~...

TensorFlow和PyTorch相继发布最新版,有何变化

原文来源:GitHub「机器人圈」编译:嗯~阿童木呀、多啦A亮Tensorflow主要特征和改进在Tensorflow库中添加封装评估量。所添加的评估量列表如下:1.深度神经网络分类器(DNNCl...

「2022 年」崔庆才 Python3 爬虫教程 - 深度学习识别滑动验证码缺口

上一节我们使用OpenCV识别了图形验证码躯壳欧。这时候就有朋友可能会说了,现在深度学习不是对图像识别很准吗?那深度学习可以用在识别滑动验证码缺口位置吗?当然也是可以的,本节我们就来了解下使用深度...

20K star!搞定 LLM 微调的开源利器

LLM(大语言模型)微调一直都是老大难问题,不仅因为微调需要大量的计算资源,而且微调的方法也很多,要去尝试每种方法的效果,需要安装大量的第三方库和依赖,甚至要接入一些框架,可能在还没开始微调就已经因为...

大模型DeepSeek本地部署后如何进行自定义调整?

1.理解模型架构a)查看深度求索官方文档或提供的源代码文件,了解模型的结构、输入输出格式以及支持的功能。模型是否为预训练权重?如果是,可以在预训练的基础上进行微调(Fine-tuning)。是否需要...

因配置不当,约5000个AI模型与数据集在公网暴露

除了可访问机器学习模型外,暴露的数据还可能包括训练数据集、超参数,甚至是用于构建模型的原始数据。前情回顾·人工智能安全动态向ChatGPT植入恶意“长期记忆”,持续窃取用户输入数据多模态大语言模型的致...

基于pytorch的深度学习人员重识别

基于pytorch的深度学习人员重识别Torchreid是一个库。基于pytorch的深度学习人员重识别。特点:支持多GPU训练支持图像的人员重识别与视频的人员重识别端到端的训练与评估简单的re...

DeepSeek本地部署:轻松训练你的AI模型

引言:为什么选择本地部署?在AI技术飞速发展的今天,越来越多的企业和个人希望将AI技术应用于实际场景中。然而,对于一些对数据隐私和计算资源有特殊需求的用户来说,云端部署可能并不是最佳选择。此时,本地部...

谷歌今天又开源了,这次是Sketch-RNN

前不久,谷歌公布了一项最新技术,可以教机器画画。今天,谷歌开源了代码。在我们研究其代码之前,首先先按要求设置Magenta环境。(https://github.com/tensorflow/magen...

Tensorflow 使用预训练模型训练的完整流程

前面已经介绍了深度学习框架Tensorflow的图像的标注和训练数据的准备工作,本文介绍一下使用预训练模型完成训练并导出训练的模型。1.选择预训练模型1.1下载预训练模型首先需要在Tensorf...

30天大模型调优学习计划(30分钟训练大模型)

30天大模型调优学习计划,结合Unsloth和Lora进行大模型微调,掌握大模型基础知识和调优方法,熟练应用。第1周:基础入门目标:了解大模型基础并熟悉Unsloth等工具的基本使用。Day1:大模...

python爬取喜马拉雅音频,json参数解析

一.抓包分析json,获取加密方式1.抓包获取音频界面f12打开抓包工具,播放一个(非vip)视频,点击“媒体”单击打开可以复制URL,发现就是我们要的音频。复制“CKwRIJEEXn-cABa0Tg...

五、JSONPath使用(Python)(json数据python)

1.安装方法pipinstalljsonpath2.jsonpath与Xpath下面表格是jsonpath语法与Xpath的完整概述和比较。Xpathjsonpath概述/$根节点.@当前节点...

Python网络爬虫的时候json=就是让你少写个json.dumps()

大家好,我是皮皮。一、前言前几天在Python白银交流群【空翼】问了一个Python网络爬虫的问题,提问截图如下:登录请求地址是这个:二、实现过程这里【甯同学】给了一个提示,如下所示:估计很多小伙伴和...