当前位置: 首页 > news >正文

【Python】文件处理(二)

目录

  • 文件处理
    • 文件与目录的属性操作
    • 文件权限操作
    • 文件与目录的高级操作
    • 文件内容格式的操作
      • JSON 文件操作
      • CSV 文件操作
      • Excel 文件操作

文件处理

文件与目录的属性操作

判断文件或目录是否存在

  1. os.path.exists(path)

    import osprint(os.path.exists("data.txt"))   # True/False
    print(os.path.exists("folder"))     # True/False
    
  2. Path.exists()

    from pathlib import Pathprint(Path("data.txt").exists())
    print(Path("folder").exists())
    

判断文件类型

  1. 判断是否是文件

    • os.path.isfile(path)
    • Path.is_file()
    import os
    from pathlib import Pathprint(os.path.isfile("data.txt"))
    print(Path("data.txt").is_file())
    
  2. 判断是否是目录

    • os.path.isdir(path)
    • Path.is_dir()
    print(os.path.isdir("folder"))
    print(Path("folder").is_dir())
    
  3. 判断是否是符号链接

    • os.path.islink(path)
    • Path.is_symlink()

获取文件大小

  1. os.path.getsize(path)

    import ossize = os.path.getsize("data.txt")
    print("文件大小:", size, "字节")
    
  2. Path.stat().st_size

    from pathlib import Pathsize = Path("data.txt").stat().st_size
    print("文件大小:", size, "字节")
    

获取文件时间属性

文件常见的时间属性有三种(具体含义依系统不同略有差异):

  • st_atime:最后访问时间(Access Time)
  • st_mtime:最后修改时间(Modify Time,内容被修改)
  • st_ctime:创建时间(Create Time,Windows);在 Unix/Linux 上可能表示元数据修改时间(Change Time)
  1. os.path.get*

    import os
    import timeprint("访问时间:", time.ctime(os.path.getatime("data.txt")))
    print("修改时间:", time.ctime(os.path.getmtime("data.txt")))
    print("创建时间:", time.ctime(os.path.getctime("data.txt")))
    
  2. Path.stat()

    from pathlib import Path
    import timep = Path("data.txt").stat()print("访问时间:", time.ctime(p.st_atime))
    print("修改时间:", time.ctime(p.st_mtime))
    print("创建时间:", time.ctime(p.st_ctime))
    

获取更多文件属性

os.stat(path)Path.stat() 可以一次性获取完整信息:

import osinfo = os.stat("data.txt")
print(info.st_size)    # 文件大小
print(info.st_mode)    # 权限
print(info.st_uid)     # 拥有者 ID(Unix)
print(info.st_gid)     # 用户组 ID(Unix)

结合案例:文件信息检查工具

from pathlib import Path
import timedef file_info(path):p = Path(path)if not p.exists():print(f"{path} 不存在")returnprint("名称:", p.name)print("类型:", "目录" if p.is_dir() else "文件")print("大小:", p.stat().st_size, "字节")print("访问时间:", time.ctime(p.stat().st_atime))print("修改时间:", time.ctime(p.stat().st_mtime))print("创建时间:", time.ctime(p.stat().st_ctime))file_info("data.txt")

文件权限操作

什么是文件权限?

在操作系统里,文件通常有 读 ®、写 (w)、执行 (x) 三种权限,针对 不同的用户类别

  • u (user):文件所有者
  • g (group):同组用户
  • o (others):其他用户
  • a (all):所有用户(user + group + others)

示例:Linux 中执行 ls -l

-rw-r--r--  1 user group  1024 Sep 25  data.txt

解释:

  • rw- → 所有者可以读写
  • r-- → 同组用户只能读
  • r-- → 其他用户只能读

修改文件权限

  1. os.chmod(path, mode)

    • 作用:修改文件权限(仅限 Unix 系统有效,Windows 对执行权限的处理有限)。
    • mode:用 八进制数字 表示权限,比如:
      • 0o777 → 所有人可读写执行
      • 0o644 → 所有者可读写,其他人可读
      • 0o600 → 仅所有者可读写

    示例:

    import os# 把 data.txt 权限改为 644 (rw-r--r--)
    os.chmod("data.txt", 0o644)
    
  2. 使用 stat 模块更直观

    stat 提供了一些常量,可以组合使用。

    import os, stat# 设置成 只读
    os.chmod("data.txt", stat.S_IREAD)# 设置成 可写
    os.chmod("data.txt", stat.S_IWRITE)# 设置成 可执行
    os.chmod("script.sh", stat.S_IEXEC)# 组合权限 (读 + 写)
    os.chmod("config.ini", stat.S_IREAD | stat.S_IWRITE)
    

检查权限

os.access(path, mode)

  • 作用:检查当前用户是否有权限访问某个文件。
  • mode 参数
    • os.F_OK → 文件是否存在
    • os.R_OK → 是否可读
    • os.W_OK → 是否可写
    • os.X_OK → 是否可执行

示例:

import osprint(os.access("data.txt", os.F_OK))  # 是否存在
print(os.access("data.txt", os.R_OK))  # 是否可读
print(os.access("data.txt", os.W_OK))  # 是否可写
print(os.access("script.sh", os.X_OK)) # 是否可执行

文件所有权(Linux/Unix 常用)

在 Linux/Unix 系统中,每个文件都有 用户 ID (uid)组 ID (gid)

  1. 查看所有者

    import osinfo = os.stat("data.txt")
    print("用户 ID:", info.st_uid)
    print("组 ID:", info.st_gid)
    
  2. 修改所有者(需要 root 权限)

    import os# 把文件的所有者改为用户 ID 1000,组 ID 1000
    os.chown("data.txt", 1000, 1000)
    

    在 Windows 系统中,os.chown() 不可用。

跨平台注意事项

  • Linux/macOS:支持完整的 chmodchown、权限检查。
  • Windows:文件系统权限机制不同,部分操作(如 chown、执行权限)无效。
  • 如果要写跨平台代码,推荐:
    • os.access() 来做权限检测
    • 避免依赖 chown,Windows 不支持

综合示例:权限管理工具

import os, statdef check_permissions(path):print(f"检查 {path} 权限:")print("存在:", os.access(path, os.F_OK))print("可读:", os.access(path, os.R_OK))print("可写:", os.access(path, os.W_OK))print("可执行:", os.access(path, os.X_OK))def set_readonly(path):os.chmod(path, stat.S_IREAD)print(f"{path} 已设为只读")def set_writable(path):os.chmod(path, stat.S_IREAD | stat.S_IWRITE)print(f"{path} 已设为可写")check_permissions("data.txt")
set_readonly("data.txt")
check_permissions("data.txt")

文件与目录的高级操作

文件复制与移动(shutil 模块)

shutil 提供了更强大的文件操作接口,常用于批量处理文件。

  1. 复制文件

    • shutil.copy(src, dst)
      复制文件内容 + 权限(不包含修改时间、元数据)。
    • shutil.copy2(src, dst)
      复制文件内容 + 权限 + 时间戳等元数据。
    import shutil# 简单复制
    shutil.copy("a.txt", "backup_a.txt")# 保留元数据复制
    shutil.copy2("a.txt", "backup_with_meta.txt")
    
  2. 复制整个目录

    • shutil.copytree(src, dst)
      递归复制目录及子目录内容。
    shutil.copytree("my_folder", "backup_folder")
    

    注意:目标目录 不能已存在,否则会报错(Python 3.8+ 可以加 dirs_exist_ok=True 来覆盖)。

  3. 移动文件/目录

    • shutil.move(src, dst)
      可以移动文件或目录,相当于剪切操作。
    # 移动文件
    shutil.move("a.txt", "subdir/a.txt")# 移动目录
    shutil.move("backup_folder", "archive/backup_folder")
    

删除操作

除了前面 os.remove()os.rmdir(),更常用的是 shutil

  • shutil.rmtree(path) → 删除整个目录树(包括所有子目录和文件)
import shutilshutil.rmtree("backup_folder")  # 小心!不可逆

文件/目录信息(元数据)

有时候需要获取文件属性(大小、创建时间、修改时间等):

  1. 使用 os.stat()

    import os
    import timestat_info = os.stat("a.txt")print("大小:", stat_info.st_size, "字节")
    print("最后修改时间:", time.ctime(stat_info.st_mtime))
    print("最后访问时间:", time.ctime(stat_info.st_atime))
    print("创建时间:", time.ctime(stat_info.st_ctime))
    
  2. 使用 pathlib.Path.stat()

    from pathlib import Pathp = Path("a.txt")
    info = p.stat()print("大小:", info.st_size)
    print("修改时间:", info.st_mtime)
    

遍历目录树

如果你需要扫描所有文件,推荐用 os.walk()pathlib.rglob()

  1. os.walk()

    import osfor root, dirs, files in os.walk("my_folder"):print("当前目录:", root)print("子目录:", dirs)print("文件:", files)
    
  2. pathlib.Path.rglob()

    from pathlib import Pathp = Path("my_folder")# 递归查找所有 txt 文件
    for file in p.rglob("*.txt"):print(file)
    

路径操作(进阶)

除了前面 os.pathjoinsplitpathlib 提供了更优雅的方式:

from pathlib import Pathp = Path("my_folder") / "subdir" / "a.txt"print("完整路径:", p.resolve())
print("父目录:", p.parent)
print("文件名:", p.name)
print("后缀:", p.suffix)
print("是否存在:", p.exists())

临时文件与目录

有时候需要在程序运行时创建临时文件/目录,Python 提供了 tempfile 模块:

import tempfile# 创建临时文件
with tempfile.TemporaryFile(mode="w+t") as tmp:tmp.write("临时内容")tmp.seek(0)print(tmp.read())  # 程序结束后自动删除# 创建临时目录
with tempfile.TemporaryDirectory() as tmpdir:print("临时目录:", tmpdir)

压缩与解压

shutil 还支持压缩与解压(ZIP、TAR 等格式):

import shutil# 压缩目录为 zip 文件
shutil.make_archive("backup", "zip", "my_folder")# 解压缩
shutil.unpack_archive("backup.zip", "unpacked_folder")

文件内容格式的操作

JSON 文件操作

在实际开发中,JSON(JavaScript Object Notation)是最常用的数据交换格式,尤其在配置文件、前后端通信、存储结构化数据时非常常见。
Python 内置的 json 模块就能轻松读写 JSON 文件。

什么是 JSON?

  • JSON 是一种 轻量级数据交换格式,结构类似 Python 的字典。
  • 数据类型对应关系
JSON 类型Python 类型
objectdict
arraylist
stringstr
numberint / float
trueTrue
falseFalse
nullNone

读写 JSON 的基础方法

  1. Python 对象 ↔ JSON 字符串

    import jsondata = {"name": "Alice","age": 25,"is_student": False,"courses": ["Math", "English"],"address": {"city": "Tokyo", "zip": "100-0001"}
    }# Python 对象 → JSON 字符串
    json_str = json.dumps(data, ensure_ascii=False, indent=4)
    print("JSON 字符串:\n", json_str)# JSON 字符串 → Python 对象
    parsed = json.loads(json_str)
    print("解析后的 Python 对象:", parsed)
    

    参数说明:

    • ensure_ascii=False → 让中文正常显示,而不是 \uXXXX 形式。
    • indent=4 → 美化缩进,便于阅读。
  2. 写入 JSON 文件

    # 写入 JSON 文件
    with open("data.json", "w", encoding="utf-8") as f:json.dump(data, f, ensure_ascii=False, indent=4)
    
  3. 读取 JSON 文件

    # 读取 JSON 文件
    with open("data.json", "r", encoding="utf-8") as f:loaded_data = json.load(f)print("从文件中读取的数据:", loaded_data)
    

高级用法

  1. 处理复杂对象(自定义类)

    默认情况下,json 不能直接序列化自定义对象,需要提供 编码和解码方法

    import json
    from datetime import datetimeclass Student:def __init__(self, name, age, enroll_date):self.name = nameself.age = ageself.enroll_date = enroll_dates = Student("Bob", 20, datetime.now())# 自定义序列化
    def encode_student(obj):if isinstance(obj, Student):return {"name": obj.name, "age": obj.age, "enroll_date": obj.enroll_date.isoformat()}if isinstance(obj, datetime):return obj.isoformat()raise TypeError("类型不支持序列化")json_str = json.dumps(s, default=encode_student, ensure_ascii=False, indent=4)
    print(json_str)
    
  2. 反序列化回对象

    def decode_student(d):if "enroll_date" in d:return Student(d["name"], d["age"], datetime.fromisoformat(d["enroll_date"]))return d# 从 JSON 恢复为 Student 对象
    student_obj = json.loads(json_str, object_hook=decode_student)
    print(student_obj.name, student_obj.age, student_obj.enroll_date)
    
  3. 按行读取 JSON(大文件处理)

    如果 JSON 文件很大,可以逐行读取,每行一个 JSON 对象(常见于日志存储)。

    with open("bigdata.json", "r", encoding="utf-8") as f:for line in f:record = json.loads(line)print(record)
    
  4. 合并多个 JSON 文件

    import json
    from pathlib import Pathmerged_data = []for file in Path("json_files").glob("*.json"):with open(file, "r", encoding="utf-8") as f:merged_data.append(json.load(f))with open("merged.json", "w", encoding="utf-8") as f:json.dump(merged_data, f, ensure_ascii=False, indent=4)
    

实战小案例:记事本存储 JSON

import json
from datetime import datetimeNOTE_FILE = "notes.json"def add_note(title, content):try:with open(NOTE_FILE, "r", encoding="utf-8") as f:notes = json.load(f)except FileNotFoundError:notes = []notes.append({"title": title,"content": content,"time": datetime.now().isoformat()})with open(NOTE_FILE, "w", encoding="utf-8") as f:json.dump(notes, f, ensure_ascii=False, indent=4)def show_notes():try:with open(NOTE_FILE, "r", encoding="utf-8") as f:notes = json.load(f)except FileNotFoundError:notes = []for n in notes:print(f"[{n['time']}] {n['title']}: {n['content']}")# 测试
add_note("学习 Python", "今天学了 JSON 文件操作")
show_notes()

CSV 文件操作

CSV(Comma-Separated Values,逗号分隔值)是最常见的数据存储格式之一,尤其在 数据分析、Excel 导入导出、数据库备份 等场景非常常见。
Python 提供了内置的 csv 模块 来处理 CSV 文件。

什么是 CSV?

  • CSV 本质上是一个 文本文件,通过 逗号(或其他分隔符) 分隔字段。
  • 常见格式:
name,age,city
Alice,25,Tokyo
Bob,30,Beijing
Charlie,22,New York

写入 CSV 文件

  1. 写入行数据

    import csvdata = [["name", "age", "city"],["Alice", 25, "Tokyo"],["Bob", 30, "Beijing"],["Charlie", 22, "New York"]
    ]with open("people.csv", "w", newline="", encoding="utf-8") as f:writer = csv.writer(f)writer.writerows(data)  # 写入多行
    

    注意:

    • newline="" → 避免写入空行(Windows 特别需要)。
    • writerow() → 写入单行。
    • writerows() → 写入多行。
  2. 使用字典写入(推荐)

    import csvdata = [{"name": "Alice", "age": 25, "city": "Tokyo"},{"name": "Bob", "age": 30, "city": "Beijing"},{"name": "Charlie", "age": 22, "city": "New York"}
    ]with open("people_dict.csv", "w", newline="", encoding="utf-8") as f:fieldnames = ["name", "age", "city"]writer = csv.DictWriter(f, fieldnames=fieldnames)writer.writeheader()   # 写入表头writer.writerows(data) # 写入数据
    

读取 CSV 文件

  1. 逐行读取

    import csvwith open("people.csv", "r", encoding="utf-8") as f:reader = csv.reader(f)for row in reader:print(row)  # 每一行是一个列表
    

    输出:

    ['name', 'age', 'city']
    ['Alice', '25', 'Tokyo']
    ['Bob', '30', 'Beijing']
    ['Charlie', '22', 'New York']
    
  2. 使用字典方式读取

    import csvwith open("people_dict.csv", "r", encoding="utf-8") as f:reader = csv.DictReader(f)for row in reader:print(row)  # 每一行是一个字典
    

    输出:

    {'name': 'Alice', 'age': '25', 'city': 'Tokyo'}
    {'name': 'Bob', 'age': '30', 'city': 'Beijing'}
    {'name': 'Charlie', 'age': '22', 'city': 'New York'}
    

    注意:所有内容会被读成字符串,需要自己转类型。

高级用法

  1. 自定义分隔符

    有时不是逗号,而是 \t(制表符)或 ;

    with open("tab_file.csv", "w", newline="", encoding="utf-8") as f:writer = csv.writer(f, delimiter="\t")writer.writerow(["name", "age", "city"])writer.writerow(["Alice", 25, "Tokyo"])
    
  2. 自定义分隔符

    有时不是逗号,而是 \t(制表符)或 ;

    with open("tab_file.csv", "w", newline="", encoding="utf-8") as f:writer = csv.writer(f, delimiter="\t")writer.writerow(["name", "age", "city"])writer.writerow(["Alice", 25, "Tokyo"])
    
  3. 转换为列表/字典

    with open("people.csv", "r", encoding="utf-8") as f:reader = csv.reader(f)data = list(reader)  # 转为列表
    print(data)with open("people_dict.csv", "r", encoding="utf-8") as f:reader = csv.DictReader(f)data = list(reader)  # 转为字典列表
    print(data)
    

实战案例:成绩表统计

假设有一个 scores.csv 文件:

name,math,english,science
Alice,90,85,92
Bob,78,88,80
Charlie,95,92,89

我们计算每个人的平均分:

import csvwith open("scores.csv", "r", encoding="utf-8") as f:reader = csv.DictReader(f)for row in reader:math = int(row["math"])eng = int(row["english"])sci = int(row["science"])avg = (math + eng + sci) / 3print(f"{row['name']} 平均分: {avg:.2f}")

输出:

Alice 平均分: 89.00
Bob 平均分: 82.00
Charlie 平均分: 92.00

Excel 文件操作

安装库

如果还没有安装:

pip install openpyxl

创建 Excel 文件

from openpyxl import Workbook# 创建工作簿
wb = Workbook()# 激活默认工作表
ws = wb.active
ws.title = "学生成绩"# 写入单元格数据
ws["A1"] = "姓名"
ws["B1"] = "数学"
ws["C1"] = "英语"ws.append(["Alice", 90, 85])
ws.append(["Bob", 78, 88])
ws.append(["Charlie", 95, 92])# 保存文件
wb.save("scores.xlsx")

注意:

  • ws["A1"] = "姓名" → 直接赋值写入。
  • ws.append([...]) → 添加一行。

读取 Excel 文件

from openpyxl import load_workbook# 打开 Excel 文件
wb = load_workbook("scores.xlsx")# 获取工作表
ws = wb["学生成绩"]# 遍历行
for row in ws.iter_rows(values_only=True):print(row)

输出:

('姓名', '数学', '英语')
('Alice', 90, 85)
('Bob', 78, 88)
('Charlie', 95, 92)

获取单元格信息

# 获取单个单元格
cell = ws["B2"]
print("值:", cell.value)
print("行:", cell.row, "列:", cell.column)# 遍历列
for col in ws.iter_cols(min_col=2, max_col=3, values_only=True):print(col)

修改 Excel

# 修改单元格
ws["C2"] = 95  # 把 Alice 的英语改成 95# 插入新行
ws.insert_rows(2)# 删除列
ws.delete_cols(2)wb.save("scores_updated.xlsx")

样式设置(美化表格)

from openpyxl.styles import Font, Alignment, PatternFill# 设置字体
ws["A1"].font = Font(bold=True, color="FFFFFF")# 设置背景色
ws["A1"].fill = PatternFill(start_color="4F81BD", end_color="4F81BD", fill_type="solid")# 居中对齐
ws["A1"].alignment = Alignment(horizontal="center", vertical="center")wb.save("scores_styled.xlsx")

多个工作表操作

# 新建工作表
ws2 = wb.create_sheet("总分")# 写入数据
ws2["A1"] = "姓名"
ws2["B1"] = "总分"# 从学生成绩表读取并计算总分
for row in ws.iter_rows(min_row=2, values_only=True):name, math, english = rowws2.append([name, math + english])wb.save("scores_with_total.xlsx")

实战案例:统计成绩并排序

from openpyxl import load_workbookwb = load_workbook("scores.xlsx")
ws = wb.active# 提取数据
data = []
for row in ws.iter_rows(min_row=2, values_only=True):name, math, english = rowtotal = math + englishdata.append((name, math, english, total))# 排序(按总分降序)
data.sort(key=lambda x: x[3], reverse=True)# 写入新表
ws_sorted = wb.create_sheet("排序结果")
ws_sorted.append(["姓名", "数学", "英语", "总分"])
for row in data:ws_sorted.append(row)wb.save("scores_sorted.xlsx")

高级功能(常用扩展)

  • 公式支持ws["D2"] = "=B2+C2"(Excel 会自动计算)
  • 合并单元格ws.merge_cells("A1:C1")
  • 冻结窗格ws.freeze_panes = "A2"(冻结第一行)
  • 自动调整列宽:需手动计算字符串长度,再设置 column_dimensions
http://www.dtcms.com/a/406022.html

相关文章:

  • 幸运飞艇网站建设设计网站流程
  • 基于vue的考研信息系统6kv17(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
  • 针对单元测试、集成测试、系统测试和验收测试(用户测试)各自的目标和测试内容不同,设计对应的各类测试用例
  • (JDK,Eclipse,Tomcat版本)Java的web配置Part1 (#by 拌面
  • 中企动力算大厂吗周口网站关键词优化
  • 用 Flink DataStream API 搭建流式 ETL从无状态到有状态、从单流到连接流
  • 上海保洁服务网站建设小网站如何做密码找回
  • FreeRTOS内存管理
  • 基于 STM32 的智能洗衣机控制系统设计与实现
  • 【开题答辩全过程】以 IT项目需求发布与管理平台为例,包含答辩的问题和答案
  • 省级旅投集团数据中台架构实战:多租户隔离与主题域建模实践
  • 分布式阳台光伏系统组成及防逆流电表功能详解
  • PostgreSQL 和 MySQL两个数据库的索引的区别
  • 论文流程1
  • 苏州正规制作网站公司去了外包简历就毁了吗
  • 上海网站建设公司哪家好?大淘客怎么自己做网站
  • 解决Markdown笔记图片失效问题:Gitee+PicGo图床搭建全攻略
  • AWS中国云中的ETL之从aurora搬数据到s3(Glue版)
  • 忘记云服务器密码怎么办?阿里云/腾讯云/AWS密码重置官方指南
  • DevOps实战(9) - 使用Arbess+GitPuk+sourcefare+PostIn搭建Java自动化部署
  • 嘉兴优化网站价格怎么做网站xml地图
  • C语言指针深度解析:从硬件架构到现代安全编程
  • Vue 自定义指令详解
  • uniapp 支付宝小程序 扩展组件 component 节点的class不生效
  • 盈利的网站网站开发还找到工作吗
  • 智能体:小白零基础入门第三期,使用 Coze 搭建一款智能语音听写助手(附喂饭级教程)
  • Vue3 + TypeScript + Ant Design Vue 实现左侧菜单动态配置与路由跳转(支持路由选中项同步 + 自动展开父菜单)
  • uniapp项目使用字体图标
  • 前端拖拽,看似简单,其实处处是坑
  • 【数据结构】队列(Queue)全面详解