python处理文件读写的核心是open()函数。1. 使用open()时需指定文件路径和操作模式,如'r'读取、'w'写入、'a'追加等;2. 推荐使用with语句确保文件正确关闭;3. 处理编码问题应明确指定encoding参数,如'utf-8'或'gbk';4. 读写大文件时应逐行或按块处理以减少内存占用;5. 文件路径应使用os.path模块进行跨平台兼容的拼接与判断。这些要点构成了python文件操作的关键实践。

用Python处理文件读写,核心就是那个内置的open()函数。它是你和文件系统打交道的入口,无论是想把数据写进去,还是从里面读出来,都离不开它。它会返回一个文件对象,然后你就可以用这个对象提供的方法来操作文件了。

说实话,Python的文件操作,特别是用open()函数,上手其实挺简单的。但要用得好,用得安全,有些细节就得注意了。

最基本的用法是这样:
立即学习“Python免费学习笔记(深入)”;
# 写入文件
try:
with open('my_document.txt', 'w', encoding='utf-8') as f:
f.write('你好,世界!\n')
f.write('这是Python写入的第二行。\n')
print("文件写入成功。")
except IOError as e:
print(f"写入文件时发生错误: {e}")
# 读取文件
try:
with open('my_document.txt', 'r', encoding='utf-8') as f:
content = f.read()
print("\n文件内容如下:")
print(content)
except FileNotFoundError:
print("文件不存在,请先确保文件已创建。")
except IOError as e:
print(f"读取文件时发生错误: {e}")这里面有几个关键点:

open()函数: 它至少需要两个参数:文件路径('my_document.txt')和操作模式('w' 或 'r')。'r' (read):只读模式,文件必须存在。这是默认模式。'w' (write):写入模式,如果文件不存在就创建,如果存在则会清空原有内容再写入。'a' (append):追加模式,如果文件不存在就创建,如果存在则在文件末尾追加内容。'x' (exclusive creation):独占创建模式,如果文件已存在则会报错。'b' (binary):二进制模式,可以和 'r', 'w', 'a', 'x' 结合使用,比如 'rb'。处理图片、视频等非文本文件时用。'+' (update):更新模式,可以和 'r', 'w', 'a', 'x' 结合使用,比如 'r+' (读写,从文件开头开始)。encoding='utf-8': 这个参数特别重要,尤其是在处理文本文件时。它告诉Python用什么编码来解读或写入文件内容。中文环境下,'utf-8' 几乎是标准答案。with open(...) as f:: 这可不是什么小细节,而是个大坑!它确保文件在操作完成后,无论是否发生异常,都会被正确关闭。忘记关闭文件可能导致数据丢失、文件损坏或者资源泄露。这是Python文件操作的黄金法则,务必牢记。文件对象f提供了多种读写方法:
f.read():读取整个文件内容,返回一个字符串(文本模式)或字节串(二进制模式)。f.readline():读取文件的一行。f.readlines():读取所有行,返回一个字符串列表,每行包含换行符。f.write(string):写入一个字符串或字节串。f.writelines(list_of_strings):写入字符串列表,但不会自动添加换行符,你需要自己加。在文件读写过程中,编码问题绝对是让人头疼的“老大难”了。你是不是也遇到过打开一个文件,结果满屏乱码,或者写入的时候直接报错UnicodeEncodeError?这通常就是编码没对上号。
比如说,你可能从一个老系统里导出了一个GBK编码的CSV文件,然后想用Python去读。如果你不指定编码,Python在Windows下默认可能用GBK,但在Linux/macOS下可能默认用UTF-8,这就直接导致了乱码或报错。
# 假设有一个GBK编码的文件 'legacy_data.txt'
# 模拟创建一个GBK文件 (实际操作中你可能直接就有)
with open('legacy_data.txt', 'w', encoding='gbk') as f:
f.write('这是一段GBK编码的中文。\n')
f.write('Python文件操作真有趣。\n')
# 尝试用错误的编码读取 (可能导致乱码或报错)
print("\n尝试用错误的编码读取 (可能乱码):")
try:
with open('legacy_data.txt', 'r', encoding='utf-8') as f:
content = f.read()
print(content)
except UnicodeDecodeError as e:
print(f"解码错误!很可能是编码不匹配: {e}")
# 用正确的编码读取
print("\n用正确的编码读取:")
try:
with open('legacy_data.txt', 'r', encoding='gbk') as f:
content = f.read()
print(content)
except Exception as e:
print(f"读取失败: {e}")解决这类问题的关键,就是明确指定encoding参数。当你不知道文件确切编码时,可以尝试几种常见的,比如'utf-8'、'gbk'、'latin-1'。如果文件内容本身就包含无法解码的字符,你还可以给open()函数的errors参数传值,比如errors='ignore'(忽略无法解码的字符)、errors='replace'(用问号或其他符号替换无法解码的字符)。但通常,最好的方法还是找出并使用正确的编码。
当你需要处理的文件特别大,比如几个GB甚至几十GB时,一股脑儿地用f.read()把所有内容读进内存,那绝对是个灾难。你的程序很可能会因为内存溢出而崩溃。这时候,我们就得讲究策略了。
最常用的高效策略是逐行读取。文件对象本身是可迭代的,这意味着你可以直接在for循环中使用它,每次迭代读取一行:
print("\n逐行读取大文件示例:")
large_file_path = 'large_log.txt'
# 模拟创建一个大文件
with open(large_file_path, 'w', encoding='utf-8') as f:
for i in range(100000): # 写入10万行
f.write(f"这是日志文件的第 {i+1} 行。\n")
line_count = 0
try:
with open(large_file_path, 'r', encoding='utf-8') as f:
for line in f: # 直接迭代文件对象,每次读一行
# print(line.strip()) # 打印每一行,可以去掉末尾的换行符
line_count += 1
if line_count % 10000 == 0:
print(f"已处理 {line_count} 行...")
print(f"总共处理了 {line_count} 行。")
except Exception as e:
print(f"处理大文件时发生错误: {e}")这种方式的优点是,Python每次只从文件中读取一小部分(通常是一行)到内存中处理,大大降低了内存占用。对于文本文件,这是最常见也是最推荐的做法。
对于二进制文件,比如处理图片或者音频数据,你可能需要按块(chunk)读取。read(size)方法可以指定读取的字节数:
print("\n按块读取二进制文件示例:")
binary_file_path = 'sample.bin'
# 模拟创建一个二进制文件
with open(binary_file_path, 'wb') as f:
f.write(b'\x00\x01\x02\x03' * 10000) # 写入大量二进制数据
chunk_size = 4096 # 每次读取4KB
bytes_read = 0
try:
with open(binary_file_path, 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk: # 如果没有更多数据,则退出循环
break
bytes_read += len(chunk)
# 这里可以处理 chunk 数据
# print(f"读取了 {len(chunk)} 字节,总共 {bytes_read} 字节。")
if bytes_read % (1024 * 1024) == 0: # 每MB打印一次
print(f"已读取 {bytes_read / (1024 * 1024):.2f} MB...")
print(f"二进制文件读取完成,总共读取 {bytes_read} 字节。")
except Exception as e:
print(f"处理二进制文件时发生错误: {e}")按块读取可以让你控制每次加载到内存的数据量,对于处理任意大小的二进制数据都非常有效。
文件路径,听起来简单,但在实际开发中,尤其是涉及到跨平台部署时,它能把你搞得焦头烂额。Windows用反斜杠\,Linux和macOS用正斜杠/,如果你的代码里硬编码了路径分隔符,那换个系统可能就跑不起来了。
解决这个问题的最佳实践,就是使用os.path模块。它提供了一系列与操作系统无关的路径操作函数。
拼接路径:os.path.join()
这是最重要的一个。它会根据当前操作系统的规则来拼接路径,避免了手动处理斜杠的麻烦。
import os
base_dir = 'data'
sub_dir = 'logs'
file_name = 'app.log'
# 错误示范:硬编码斜杠,不跨平台
# full_path_bad = base_dir + '/' + sub_dir + '/' + file_name
# 正确做法:使用 os.path.join()
full_path_good = os.path.join(base_dir, sub_dir, file_name)
print(f"拼接后的路径: {full_path_good}")
# 在Windows上可能输出: data\logs\app.log
# 在Linux/macOS上可能输出: data/logs/app.log判断路径是否存在:os.path.exists()
在尝试打开文件之前,最好先检查一下它是否存在,这样可以避免FileNotFoundError。
if os.path.exists(full_path_good):
print(f"文件或目录 '{full_path_good}' 存在。")
else:
print(f"文件或目录 '{full_path_good}' 不存在。")
# 可以选择创建目录
# os.makedirs(os.path.dirname(full_path_good), exist_ok=True)获取目录名和文件名:os.path.dirname() 和 os.path.basename()
这两个函数可以帮你方便地从完整路径中提取目录部分和文件名部分。
directory = os.path.dirname(full_path_good)
base_name = os.path.basename(full_path_good)
print(f"目录部分: {directory}")
print(f"文件名部分: {base_name}")绝对路径和相对路径:os.path.abspath()
当你需要确保路径是完整的,不依赖于当前工作目录时,可以使用os.path.abspath()将其转换为绝对路径。
relative_path = 'temp/report.txt'
absolute_path = os.path.abspath(relative_path)
print(f"相对路径: {relative_path}")
print(f"绝对路径: {absolute_path}")总的来说,处理文件路径时,多用os.path模块,少写硬编码的斜杠,你的代码会健壮很多,也更容易在不同环境中运行。这是一个非常值得投入时间去理解和实践的“小”细节。
以上就是如何用Python实现文件读写?open函数使用技巧的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号