文件操作#
文件操作是编程中的常见任务。Python 提供了简单而强大的文件操作功能。
打开和关闭文件#
open() 函数#
# 基本语法:open(file, mode='r', encoding=None)
file = open("data.txt", "r")
content = file.read()
file.close() # 必须关闭文件文件模式#
# 'r' - 只读模式(默认)
file = open("data.txt", "r")
# 'w' - 写入模式(覆盖)
file = open("data.txt", "w")
# 'a' - 追加模式
file = open("data.txt", "a")
# 'x' - 创建模式(文件不存在时创建)
file = open("new_file.txt", "x")
# 'b' - 二进制模式
file = open("image.jpg", "rb")
# 't' - 文本模式(默认)
file = open("data.txt", "rt")
# '+' - 读写模式
file = open("data.txt", "r+") # 读写
file = open("data.txt", "w+") # 读写(覆盖)with 语句(推荐)#
使用 with 语句可以自动关闭文件,即使发生异常也会关闭。
# 基本用法
with open("data.txt", "r") as file:
content = file.read()
# 文件自动关闭
# 多个文件
with open("input.txt", "r") as infile, open("output.txt", "w") as outfile:
content = infile.read()
outfile.write(content)读取文件#
read() 方法#
# 读取整个文件
with open("data.txt", "r") as file:
content = file.read()
print(content)
# 读取指定字节数
with open("data.txt", "r") as file:
content = file.read(100) # 读取前100个字符readline() 方法#
# 读取一行
with open("data.txt", "r") as file:
line = file.readline()
print(line)
# 读取所有行(逐行)
with open("data.txt", "r") as file:
while True:
line = file.readline()
if not line:
break
print(line.strip()) # strip()去除换行符readlines() 方法#
# 读取所有行,返回列表
with open("data.txt", "r") as file:
lines = file.readlines()
for line in lines:
print(line.strip())迭代文件对象#
# 直接迭代文件对象(推荐,内存效率高)
with open("data.txt", "r") as file:
for line in file:
print(line.strip())写入文件#
write() 方法#
# 写入字符串
with open("output.txt", "w") as file:
file.write("Hello, World!\n")
file.write("这是第二行\n")
# 写入多行
lines = ["第一行\n", "第二行\n", "第三行\n"]
with open("output.txt", "w") as file:
file.writelines(lines)追加模式#
# 追加内容到文件末尾
with open("log.txt", "a") as file:
file.write("新的日志条目\n")文件位置操作#
with open("data.txt", "r") as file:
# 获取当前位置
position = file.tell()
print(f"当前位置: {position}")
# 移动到指定位置
file.seek(0) # 移动到文件开头
file.seek(10) # 移动到第10个字节
file.seek(0, 2) # 移动到文件末尾(0=起始位置,2=从末尾)
# 读取当前位置之后的内容
content = file.read()文件路径操作#
os.path 模块#
import os
# 连接路径
path = os.path.join("folder", "subfolder", "file.txt")
# 获取目录名
dirname = os.path.dirname("/path/to/file.txt") # /path/to
# 获取文件名
filename = os.path.basename("/path/to/file.txt") # file.txt
# 分离文件名和扩展名
name, ext = os.path.splitext("file.txt") # ('file', '.txt')
# 检查路径是否存在
exists = os.path.exists("/path/to/file.txt")
# 检查是否为文件
is_file = os.path.isfile("/path/to/file.txt")
# 检查是否为目录
is_dir = os.path.isdir("/path/to/directory")
# 获取绝对路径
abs_path = os.path.abspath("file.txt")
# 获取当前工作目录
cwd = os.getcwd()pathlib 模块(Python 3.4+,推荐)#
from pathlib import Path
# 创建Path对象
path = Path("folder/file.txt")
# 路径操作
path.parent # 父目录
path.name # 文件名
path.stem # 文件名(不含扩展名)
path.suffix # 扩展名
path.exists() # 是否存在
path.is_file() # 是否为文件
path.is_dir() # 是否为目录
# 路径连接
path = Path("folder") / "subfolder" / "file.txt"
# 读取文件
content = path.read_text(encoding="utf-8")
# 写入文件
path.write_text("content", encoding="utf-8")
# 遍历目录
for file in Path(".").iterdir():
print(file)CSV 文件处理#
csv 模块#
import csv
# 读取CSV文件
with open("data.csv", "r", encoding="utf-8") as file:
reader = csv.reader(file)
for row in reader:
print(row)
# 使用字典读取(推荐)
with open("data.csv", "r", encoding="utf-8") as file:
reader = csv.DictReader(file)
for row in reader:
print(row["name"], row["age"])
# 写入CSV文件
with open("output.csv", "w", encoding="utf-8", newline="") as file:
writer = csv.writer(file)
writer.writerow(["name", "age", "city"])
writer.writerow(["Alice", "30", "Beijing"])
writer.writerow(["Bob", "25", "Shanghai"])
# 使用字典写入
with open("output.csv", "w", encoding="utf-8", newline="") as file:
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({"name": "Alice", "age": "30", "city": "Beijing"})JSON 文件处理#
import json
# 读取JSON文件
with open("data.json", "r", encoding="utf-8") as file:
data = json.load(file)
print(data["name"])
# 写入JSON文件
data = {"name": "Alice", "age": 30, "city": "Beijing"}
with open("output.json", "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=2)
# ensure_ascii=False: 允许非ASCII字符
# indent=2: 格式化输出,缩进2个空格上下文管理器(深入)#
自定义上下文管理器#
# 使用类实现
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
return False # 返回False表示不抑制异常
# 使用
with FileManager("data.txt", "r") as file:
content = file.read()
# 使用contextlib模块(更简单)
from contextlib import contextmanager
@contextmanager
def file_manager(filename, mode):
file = open(filename, mode)
try:
yield file
finally:
file.close()
# 使用
with file_manager("data.txt", "r") as file:
content = file.read()文件操作最佳实践#
1. 总是使用 with 语句#
# 好的做法
with open("data.txt", "r") as file:
content = file.read()
# 不好的做法
file = open("data.txt", "r")
content = file.read()
file.close() # 如果发生异常,文件可能不会关闭2. 指定编码#
# 好的做法
with open("data.txt", "r", encoding="utf-8") as file:
content = file.read()
# 不好的做法(依赖系统默认编码)
with open("data.txt", "r") as file:
content = file.read()3. 处理文件不存在的情况#
from pathlib import Path
file_path = Path("data.txt")
if file_path.exists():
with open(file_path, "r", encoding="utf-8") as file:
content = file.read()
else:
print("文件不存在")4. 大文件处理#
# 对于大文件,逐行读取而不是一次性读取全部
with open("large_file.txt", "r", encoding="utf-8") as file:
for line in file:
process(line) # 处理每一行5. 二进制文件#
# 读取二进制文件
with open("image.jpg", "rb") as file:
data = file.read()
# 写入二进制文件
with open("copy.jpg", "wb") as file:
file.write(data)实际应用示例#
def read_config(filename):
"""读取配置文件"""
config = {}
with open(filename, "r", encoding="utf-8") as file:
for line in file:
line = line.strip()
if line and not line.startswith("#"):
key, value = line.split("=", 1)
config[key.strip()] = value.strip()
return config
def write_log(message, logfile="app.log"):
"""写入日志"""
from datetime import datetime
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open(logfile, "a", encoding="utf-8") as file:
file.write(f"[{timestamp}] {message}\n")下一步#
掌握了文件操作后,可以学习: