一、文件打开模式
文本模式
概念定义
文本模式是Python中文件操作的基本模式,主要包括:
'r':只读模式(默认)'w':写入模式(覆盖)'a':追加模式
这些模式决定了文件如何被打开和操作。
使用场景
'r':当只需要读取文件内容时使用'w':当需要创建新文件或覆盖已有文件时使用'a':当需要在文件末尾追加内容而不影响原有内容时使用
常见误区
- 使用
'w'模式会立即清空文件内容,即使不写入任何内容 - 以
'r'模式打开不存在的文件会引发FileNotFoundError - Windows和Linux系统的换行符处理不同(
\r\nvs\n)
示例代码
# 读取文件
with open('example.txt', 'r') as f:
content = f.read()
# 写入文件(覆盖)
with open('example.txt', 'w') as f:
f.write("Hello World")
# 追加内容
with open('example.txt', 'a') as f:
f.write("\nAppended text")
二进制模式
概念定义
二进制模式是Python中文件操作的一种模式,通过在模式字符串中添加’b’来表示(如’rb’、‘wb’、‘ab’)。它表示以二进制形式而非文本形式读写文件数据。
使用场景
- 处理非文本文件(如图片、音频、视频等)
- 需要精确控制字节级数据时
- 跨平台操作时保持数据一致性(避免换行符转换问题)
常见误区或注意事项
- 二进制模式下读写的是bytes对象而非str对象
- 在Windows平台上,二进制模式可以避免换行符(\n)被自动转换为\r\n
- 二进制模式不能与编码参数(encoding)同时使用
示例代码
# 写入二进制数据
with open('data.bin', 'wb') as f:
f.write(b'\x48\x65\x6c\x6c\x6f') # 写入"Hello"的二进制表示
# 读取二进制数据
with open('data.bin', 'rb') as f:
data = f.read() # 返回bytes对象: b'Hello'
print(data) # 输出: b'Hello'
编码参数指定(encoding=‘utf-8’)
概念定义
编码参数指定是指在文件操作或字符串处理时,明确声明使用的字符编码格式。encoding='utf-8'表示使用UTF-8编码格式来处理文本数据。
使用场景
- 文件读写操作(如
open()函数) - 字符串编码/解码(如
str.encode()和bytes.decode()方法) - 网络数据传输
- 数据库交互
常见误区或注意事项
- 不指定编码可能导致在不同平台上出现乱码
- Windows系统默认编码通常是
cp1252,与utf-8不兼容 - 处理非ASCII字符时(如中文、表情符号),必须明确指定编码
- Python 3默认使用
utf-8编码,但显式声明更安全
示例代码
# 文件读写示例
with open('example.txt', 'r', encoding='utf-8') as f:
content = f.read()
with open('output.txt', 'w', encoding='utf-8') as f:
f.write("这是一段UTF-8编码的中文文本")
# 字符串编码示例
text = "你好,世界!"
encoded = text.encode('utf-8') # 转换为UTF-8字节
decoded = encoded.decode('utf-8') # 转换回字符串
二、文本文件操作
read()/readline()/readlines()方法
概念定义
这三个方法都是Python中用于从文件对象读取内容的方法:
read():读取整个文件内容,返回一个字符串readline():读取文件的一行内容,返回字符串readlines():读取所有行,返回包含各行内容的列表
使用场景
read():适合读取小文件或需要一次性处理全部内容时readline():适合逐行处理大文件,避免内存问题readlines():需要按行处理且文件不大时使用
常见误区或注意事项
read()会一次性加载整个文件到内存,大文件可能导致内存不足readline()在文件末尾会返回空字符串,可作为循环终止条件readlines()也会加载整个文件到内存,大文件慎用- 文件读取后指针会移动,再次调用可能返回不同结果
示例代码
# 使用read()
with open('example.txt', 'r') as f:
content = f.read() # 整个文件内容作为一个字符串
print(content)
# 使用readline()
with open('example.txt', 'r') as f:
line = f.readline() # 只读取第一行
while line:
print(line, end='')
line = f.readline()
# 使用readlines()
with open('example.txt', 'r') as f:
lines = f.readlines() # 所有行作为列表
for line in lines:
print(line, end='')
write()/writelines()方法
概念定义
write()和writelines()是Python中文件对象用于写入数据的两个方法:
write():将单个字符串写入文件writelines():将一个字符串列表(或其他可迭代对象)写入文件
使用场景
-
write()适用于:- 写入单个字符串
- 需要精确控制写入内容时
- 追加内容到文件末尾
-
writelines()适用于:- 批量写入多个字符串
- 需要将列表内容快速写入文件时
- 处理多行文本时
常见误区或注意事项
writelines()不会自动添加换行符,需要手动包含\n- 两种方法都不会自动关闭文件,需要使用
with语句或手动close() - 写入前需要确保文件以写入模式打开(‘w’或’a’)
writelines()参数可以是任何可迭代对象,不限于列表
示例代码
# write()示例
with open('example.txt', 'w') as f:
f.write("Hello, World!\n")
f.write("This is a test.\n")
# writelines()示例
lines = ["First line\n", "Second line\n", "Third line\n"]
with open('example.txt', 'a') as f: # 追加模式
f.writelines(lines)
# 等效的write()实现
with open('example.txt', 'a') as f:
for line in lines:
f.write(line)
with语句自动关闭文件
概念定义
with语句是Python中用于资源管理的一种语法结构,它会自动处理资源的打开和关闭。当与文件操作结合使用时,with语句可以确保文件在使用完毕后被正确关闭,即使在处理文件时发生异常也是如此。
使用场景
- 文件读写操作
- 需要确保资源被正确释放的场景
- 简化资源管理的代码
常见误区或注意事项
- 不要在
with块外继续使用已关闭的文件对象 with语句只能管理支持上下文协议的对象(如文件对象)- 多个文件可以同时在一个
with语句中打开
示例代码
# 读取文件(自动关闭)
with open('example.txt', 'r') as file:
content = file.read()
print(content)
# 写入文件(自动关闭)
with open('output.txt', 'w') as file:
file.write('Hello, World!')
# 同时打开多个文件
with open('file1.txt', 'r') as f1, open('file2.txt', 'w') as f2:
data = f1.read()
f2.write(data)
行结束符处理(\n, \r\n)
概念定义
行结束符(Line Ending)是文本文件中用于标记一行结束的特殊字符。常见的行结束符有两种:
\n(LF,Line Feed):Unix/Linux 和 macOS 系统的默认行结束符。\r\n(CRLF,Carriage Return + Line Feed):Windows 系统的默认行结束符。
使用场景
- 跨平台文本处理:在不同操作系统之间交换文本文件时,行结束符的差异可能导致显示或解析问题。
- 文件读写:Python 的文件操作(如
open())可以自动处理行结束符,但有时需要手动控制。 - 网络协议:某些协议(如 HTTP)要求使用特定的行结束符(通常是
\r\n)。
常见误区或注意事项
- 二进制模式 vs 文本模式:
- 在文本模式(
open(file, 'r')或open(file, 'w'))下,Python 会自动转换行结束符为当前系统的默认格式。 - 在二进制模式(
open(file, 'rb')或open(file, 'wb'))下,行结束符会原样保留。
- 在文本模式(
- 字符串处理:手动拼接字符串时,需注意行结束符的一致性。
- 正则表达式:匹配行结束符时,可能需要同时处理
\n和\r\n(例如使用\r?\n)。
示例代码
# 示例1:自动转换行结束符(文本模式)
with open('unix_file.txt', 'w', newline='\n') as f: # 明确指定行结束符
f.write('Unix line ending\n')
with open('windows_file.txt', 'w', newline='\r\n') as f:
f.write('Windows line ending\r\n')
# 示例2:保留原始行结束符(二进制模式)
with open('mixed_file.txt', 'rb') as f:
content = f.read() # 行结束符不会被转换
print(content) # 可能包含混合的 \n 和 \r\n
# 示例3:手动替换行结束符
text = 'Line1\r\nLine2\nLine3\r\n'
normalized_text = text.replace('\r\n', '\n') # 统一为 Unix 风格
三、二进制文件操作
字节串(bytes)处理
概念定义
字节串(bytes)是 Python 中的一种不可变序列类型,用于表示二进制数据。它由 0 到 255 之间的整数组成,每个整数代表一个字节的值。字节串通常用于处理文件 I/O、网络通信等需要直接操作二进制数据的场景。
使用场景
- 读取或写入二进制文件(如图片、音频等)
- 网络通信中传输原始数据
- 加密/解密操作
- 与底层系统交互时处理原始字节
常见误区或注意事项
- 字节串是不可变的,类似字符串,修改需要创建新对象
- 字节串与字符串(str)是不同的类型,不能直接拼接或比较
- 编码/解码时要注意使用正确的字符编码(如 UTF-8、ASCII 等)
- 字节串中的每个元素是整数(0-255),不是字符
示例代码
# 创建字节串
b1 = b'hello' # 使用 b 前缀创建 ASCII 字节串
b2 = bytes([104, 101, 108, 108, 111]) # 从整数列表创建
b3 = bytes('你好', encoding='utf-8') # 从字符串编码创建
# 基本操作
print(b1[0]) # 输出: 104 (h 的 ASCII 码)
print(b1 + b' world') # 输出: b'hello world'
# 编码/解码
text = b1.decode('ascii') # 字节串转字符串
binary = text.encode('utf-8') # 字符串转字节串
# 文件操作
with open('image.jpg', 'rb') as f: # 以二进制模式读取
data = f.read() # 返回 bytes 对象
struct模块打包/解包
概念定义
struct模块用于在Python值和C结构体之间进行转换,主要用于处理二进制数据。它提供了pack()和unpack()函数,可以将数据按照指定的格式字符串进行打包和解包。
使用场景
- 处理二进制文件格式(如图片、音频等)
- 网络协议通信(处理二进制协议头)
- 与C语言程序交互(数据交换)
常见格式字符
| 字符 | C类型 | Python类型 | 字节数 |
|---|---|---|---|
b | signed char | int | 1 |
B | unsigned char | int | 1 |
h | short | int | 2 |
H | unsigned short | int | 2 |
i | int | int | 4 |
I | unsigned int | int | 4 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | bytes | 1 |
示例代码
import struct
# 打包数据
packed_data = struct.pack('i4s f', 123, b'abcd', 3.14)
print(packed_data) # b'{\x00\x00\x00abcd\xc3\xf5H@'
# 解包数据
unpacked_data = struct.unpack('i4s f', packed_data)
print(unpacked_data) # (123, b'abcd', 3.140000104904175)
注意事项
- 格式字符串中的字符顺序必须与数据顺序严格匹配
- 打包和解包时使用相同的格式字符串
- 处理字符串时需要使用bytes类型(Python 3中)
- 注意字节序问题(
<小端,>大端,!网络字节序) - 整数类型要注意符号问题(signed/unsigned)
seek()/tell() 定位操作
概念定义
seek() 和 tell() 是 Python 文件对象提供的两个方法,用于在文件中进行定位操作:
seek(offset, whence=0):移动文件指针到指定位置offset:偏移量(字节数)whence:基准位置(0=文件开头,1=当前位置,2=文件末尾)
tell():返回当前文件指针的位置(字节数)
使用场景
- 随机访问大文件时快速定位到特定位置
- 需要重复读取文件某部分内容时
- 处理二进制文件时需要精确定位
注意事项
- 文本模式下(‘r’/‘w’):
seek()只能相对于文件开头定位(whence=0)- 某些编码(如UTF-8)可能导致定位不精确
- 二进制模式下(‘rb’/‘wb’):
- 可以使用所有 whence 参数
- 定位更加精确可靠
- 写入后需要 flush() 或关闭文件才能保证 tell() 返回正确位置
示例代码
# 二进制模式示例
with open('data.bin', 'rb') as f:
print(f.tell()) # 输出: 0 (起始位置)
f.seek(10) # 移动到第10字节
print(f.tell()) # 输出: 10
f.seek(-5, 1) # 从当前位置向前移动5字节
print(f.tell()) # 输出: 5
# 文本模式示例
with open('text.txt', 'r') as f:
f.seek(5) # 移动到第5个字符
print(f.read(3)) # 读取3个字符
缓冲区设置(buffering参数)
概念定义
在Python中,buffering参数用于控制文件I/O操作的缓冲行为。缓冲是一种临时存储数据的机制,可以减少频繁的I/O操作,提高性能。buffering参数可以在open()函数中指定。
使用场景
- 无缓冲(buffering=0):适用于需要立即写入或读取的场景,如日志文件。
- 行缓冲(buffering=1):适用于文本模式下的逐行处理,如实时监控日志。
- 固定大小缓冲(buffering>1):适用于二进制模式下的批量读写,如大文件处理。
常见误区或注意事项
- 二进制模式:在二进制模式下,
buffering只能是0或1,或者一个表示缓冲区大小的正整数。 - 文本模式:在文本模式下,
buffering=1表示行缓冲,buffering=0是不允许的(会引发ValueError)。 - 默认值:如果不指定
buffering,Python会根据文件类型和模式选择默认的缓冲策略(通常是行缓冲或固定大小缓冲)。
示例代码
# 无缓冲模式(仅适用于二进制模式)
with open('example.bin', 'wb', buffering=0) as f:
f.write(b'Hello, World!')
# 行缓冲模式(文本模式)
with open('example.txt', 'w', buffering=1) as f:
f.write('Hello, World!\n')
# 固定大小缓冲(二进制模式,缓冲区大小为4096字节)
with open('example.bin', 'wb', buffering=4096) as f:
f.write(b'Hello, World!')
四、常见文件格式处理
CSV文件(csv模块)
概念定义
CSV(Comma-Separated Values)是一种简单的文件格式,用于存储表格数据(如电子表格或数据库)。Python的csv模块提供了读取和写入CSV文件的功能。
使用场景
- 数据交换:在不同系统之间传输表格数据
- 数据存储:保存简单的表格结构数据
- 数据分析:作为数据分析的输入/输出格式
常见误区或注意事项
- 分隔符不一定是逗号,也可能是制表符或其他字符
- 文件可能有标题行(列名)也可能没有
- 数据中可能包含换行符或特殊字符,需要正确处理
- 编码问题:建议明确指定文件编码(如utf-8)
示例代码
import csv
# 写入CSV文件
with open('data.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['姓名', '年龄', '城市']) # 写入标题行
writer.writerow(['张三', 25, '北京'])
writer.writerow(['李四', 30, '上海'])
# 读取CSV文件
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
使用字典方式读写(推荐)
# 写入
with open('data_dict.csv', 'w', newline='', encoding='utf-8') as f:
fieldnames = ['name', 'age', 'city']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'name': '王五', 'age': 28, 'city': '广州'})
# 读取
with open('data_dict.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['name'], row['age'])
JSON文件(json模块)
概念定义
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生成。Python中的json模块提供了处理JSON数据的功能,可以将Python对象转换为JSON字符串(序列化),或将JSON字符串转换为Python对象(反序列化)。
使用场景
- 与Web API交互时发送或接收数据
- 存储配置信息或简单数据
- 在不同编程语言之间交换数据
- 持久化Python数据结构
常见误区或注意事项
- JSON中的键必须是字符串类型(Python中会强制转换为str)
- JSON不支持Python特有的数据类型(如集合、复数等)
- 序列化时,datetime对象等需要额外处理
- 反序列化时,JSON中的null会转换为Python的None
- 处理大文件时应考虑使用
json.load()和json.dump()替代内存中的操作
示例代码
import json
# 序列化(Python对象 → JSON字符串)
data = {
"name": "Alice",
"age": 30,
"hobbies": ["reading", "hiking"],
"married": False
}
json_str = json.dumps(data, indent=4) # indent参数用于美化输出
print(json_str)
# 反序列化(JSON字符串 → Python对象)
json_data = '{"name": "Bob", "age": 25, "city": "New York"}'
python_obj = json.loads(json_data)
print(python_obj["name"])
# 文件操作
# 写入JSON文件
with open('data.json', 'w') as f:
json.dump(data, f)
# 读取JSON文件
with open('data.json', 'r') as f:
loaded_data = json.load(f)
print(loaded_data)
XML文件(xml.etree.ElementTree)
概念定义
xml.etree.ElementTree是Python标准库中用于解析和操作XML文件的模块。它提供了一种简单高效的方式来处理XML数据,将XML文档解析为树形结构,便于遍历和修改。
使用场景
- 读取和解析XML配置文件
- 处理Web服务返回的XML数据
- 生成XML文档
- 转换XML数据格式
常见误区或注意事项
- 对于大型XML文件,考虑使用
iterparse()方法进行增量解析以避免内存问题 - XML命名空间处理需要特别注意,可能需要手动添加或移除命名空间前缀
- 修改XML树后需要显式调用写入方法才能保存更改
- 不是所有XML特性都支持(如DTD验证)
示例代码
import xml.etree.ElementTree as ET
# 解析XML文件
tree = ET.parse('example.xml')
root = tree.getroot()
# 遍历元素
for child in root:
print(child.tag, child.attrib)
# 查找特定元素
for elem in root.iter('item'):
print(elem.text)
# 创建新元素并添加
new_elem = ET.Element("new_tag")
new_elem.text = "New content"
root.append(new_elem)
# 保存修改
tree.write('modified.xml')
pickle 序列化
概念定义
pickle 是 Python 内置的序列化模块,用于将 Python 对象转换为字节流(序列化),或将字节流转换回 Python 对象(反序列化)。它能够处理几乎所有 Python 数据类型,包括自定义对象。
使用场景
- 将 Python 对象保存到文件或数据库中
- 通过网络传输 Python 对象
- 在不同 Python 程序间共享数据
- 缓存计算结果
常见误区或注意事项
- 安全性问题:不要反序列化不受信任的数据,pickle 可以执行任意代码
- 版本兼容性:不同 Python 版本间的 pickle 文件可能不兼容
- 性能问题:对于大型对象,pickle 可能不是最高效的选择
- 不可序列化对象:某些对象(如文件句柄、数据库连接)无法被 pickle
示例代码
import pickle
# 序列化示例
data = {'name': 'Alice', 'age': 25, 'scores': [88, 92, 95]}
serialized = pickle.dumps(data) # 序列化为字节流
with open('data.pkl', 'wb') as f:
pickle.dump(data, f) # 序列化并保存到文件
# 反序列化示例
loaded_data = pickle.loads(serialized) # 从字节流加载
with open('data.pkl', 'rb') as f:
file_data = pickle.load(f) # 从文件加载
print(loaded_data) # 输出: {'name': 'Alice', 'age': 25, 'scores': [88, 92, 95]}
五、文件路径处理
os.path 模块操作
概念定义
os.path 是 Python 标准库中的一个模块,用于处理文件路径相关的操作。它提供了一系列函数来解析、构造和操作文件路径,这些函数可以跨平台使用(Windows、Linux、macOS 等)。
使用场景
- 拼接路径:在不同操作系统下正确拼接路径。
- 检查路径是否存在:判断文件或目录是否存在。
- 获取路径信息:提取文件名、目录名、扩展名等。
- 规范化路径:处理路径中的冗余符号(如
./或../)。
常见误区或注意事项
- 路径分隔符:不同操作系统使用不同的路径分隔符(Windows 用
\,Linux/macOS 用/),os.path会自动处理。 - 路径存在性检查:
os.path.exists()只能检查路径是否存在,不能区分是文件还是目录(需用os.path.isfile()或os.path.isdir())。 - 相对路径与绝对路径:
os.path.abspath()可以将相对路径转为绝对路径,但不会检查路径是否存在。
示例代码
import os.path
# 拼接路径
path = os.path.join("folder", "subfolder", "file.txt")
print(path) # 输出: folder/subfolder/file.txt(Linux/macOS)或 folder\subfolder\file.txt(Windows)
# 检查路径是否存在
if os.path.exists(path):
print("路径存在")
else:
print("路径不存在")
# 获取文件名和扩展名
filename = os.path.basename(path) # file.txt
dirname = os.path.dirname(path) # folder/subfolder
name, ext = os.path.splitext(filename) # name=file, ext=.txt
# 转为绝对路径
abs_path = os.path.abspath("file.txt")
print(abs_path) # 输出当前工作目录下的绝对路径
pathlib模块:面向对象的路径操作
概念定义
pathlib是Python 3.4+引入的标准库模块,提供了面向对象的文件系统路径操作方式。它用Path类替代传统的字符串路径,将路径操作封装为对象方法。
核心优势
- 跨平台路径分隔符自动处理(Windows用
\,Unix用/) - 链式方法调用更直观
- 避免手动拼接路径字符串
常用操作示例
创建Path对象
from pathlib import Path
# 当前目录
p = Path('.')
# 绝对路径
p = Path('/usr/bin/python3')
# 相对路径
p = Path('docs/readme.txt')
路径拼接
config_path = Path('config') / 'settings.ini' # 自动处理路径分隔符
常用方法
p = Path('data/sample.txt')
# 获取文件名
print(p.name) # 'sample.txt'
# 获取父目录
print(p.parent) # 'data'
# 判断文件类型
print(p.is_file()) # True/False
# 读取文件内容
content = p.read_text()
注意事项
- 路径对象不可变,所有修改操作都会返回新对象
- 部分方法(如
mkdir())需要显式调用才会实际执行文件系统操作 - 旧版代码可能需要通过
str(path_obj)转换为字符串
实际应用场景
# 批量处理目录下的文件
for py_file in Path('src').glob('*.py'):
print(f"Processing {py_file.name}")
content = py_file.read_text()
# 处理文件内容...
相对路径与绝对路径
概念定义
- 绝对路径:从文件系统的根目录开始的完整路径,可以唯一确定文件或目录的位置。例如:
/home/user/project/file.txt - 相对路径:相对于当前工作目录的路径,不包含根目录信息。例如:
./project/file.txt或../other_project/file.txt
使用场景
- 绝对路径适用于:
- 需要明确指定文件位置时
- 脚本需要在任何目录下运行时
- 相对路径适用于:
- 项目内部文件引用
- 需要保持项目目录结构灵活性的场景
常见误区
- 在共享代码中使用绝对路径会导致在其他机器上无法运行
- 相对路径依赖于当前工作目录,在不同目录执行脚本可能会出错
- 混淆路径分隔符(Windows用
\,Unix用/)
示例代码
import os
# 获取当前工作目录
current_dir = os.getcwd()
print(f"当前目录: {current_dir}")
# 使用绝对路径
abs_path = "/home/user/project/data.txt"
print(f"绝对路径: {abs_path}")
# 使用相对路径
rel_path = "./data/data.txt"
print(f"相对路径: {rel_path}")
# 将相对路径转为绝对路径
full_path = os.path.abspath(rel_path)
print(f"转换后的绝对路径: {full_path}")
注意事项
- 在Python中建议使用
os.path模块处理路径,可以自动适应不同操作系统 - 跨平台项目应优先使用相对路径
- 使用
__file__获取当前脚本所在目录,再构建相对路径更可靠
跨平台路径分隔符处理
概念定义
跨平台路径分隔符处理是指在不同的操作系统(如Windows、Linux、macOS)上正确处理文件路径分隔符的差异。Windows使用反斜杠(\),而类Unix系统(如Linux、macOS)使用正斜杠(/)。
使用场景
- 编写需要在多个操作系统上运行的Python脚本时
- 处理用户输入的文件路径时
- 构建跨平台应用程序时
常见误区或注意事项
- 避免在代码中硬编码路径分隔符(如直接写
C:\Users或/home/user) - 注意Windows路径中的反斜杠在Python字符串中是转义字符,需要转义(
\\)或使用原始字符串(r"path") - 不要假设所有路径都是绝对路径或相对路径
示例代码
import os
# 正确构建跨平台路径
path = os.path.join('folder', 'subfolder', 'file.txt') # 自动使用正确的分隔符
# 标准化路径(统一分隔符)
normalized_path = os.path.normpath('folder\\subfolder/file.txt') # 转换为当前系统的标准格式
# 获取当前系统的路径分隔符
separator = os.sep # Windows返回'\',Linux/macOS返回'/'
# 示例:处理用户输入路径
user_path = input("请输入文件路径: ")
corrected_path = os.path.normpath(user_path) # 自动修正分隔符



4273

被折叠的 条评论
为什么被折叠?



