Python使用os模块操作文件与目录的完整指南

好的,这是一个关于 Python os 模块操作文件与目录的完整指南。os 模块是 Python 标准库中用于与操作系统进行交互的核心模块,它提供了丰富的方法来操作文件系统。

我们将从基础概念开始,逐步深入到常用操作、最佳实践以及一些实用技巧。

图片[1]_Python使用os模块操作文件与目录的完整指南_知途无界

1. 核心概念:路径

在操作文件和目录之前,必须理解 ​路径​ 的概念。

  • 绝对路径​:从文件系统的根目录开始的完整路径。
    • Windows: C:\Users\YourName\Documents\file.txt
    • Linux/macOS: /home/yourname/documents/file.txt
  • 相对路径​:相对于当前工作目录的路径。
    • ./my_script.py:当前目录下的 my_script.py 文件。
    • ../data/input.csv:上级目录中的 data 文件夹下的 input.csv 文件。
    • subdir/file.txt:当前目录下 subdir 子文件夹中的 file.txt 文件。

重要提示​:不同操作系统的路径分隔符不同(Windows 使用 \,Linux/macOS 使用 /)。为了避免代码在不同系统上出错,​强烈建议使用 os.path.join() 函数来拼接路径,它会自动使用正确的分隔符。

import os

# 不好的做法(硬编码分隔符)
path_bad = "folder" + "/" + "subfolder" + "/" + "file.txt" # Linux/macOS
path_bad_win = "folder" + "\\" + "subfolder" + "\\" + "file.txt" # Windows, 注意转义

# 好的做法(跨平台)
path_good = os.path.join("folder", "subfolder", "file.txt")
print(path_good)
# 在 Linux/macOS 输出: folder/subfolder/file.txt
# 在 Windows 输出: folder\subfolder\file.txt

2. 获取和改变工作目录

  • os.getcwd(): 获取当前工作目录。
  • os.chdir(path): 改变当前工作目录。
import os

# 获取当前工作目录
current_dir = os.getcwd()
print(f"当前工作目录: {current_dir}")

# 改变工作目录
os.chdir('/tmp') # Linux/macOS 示例
# os.chdir(r'C:\Temp') # Windows 示例,使用 raw string 避免转义问题
new_dir = os.getcwd()
print(f"新的工作目录: {new_dir}")

3. 列出目录内容

  • os.listdir(path='.'): 返回指定路径下的所有文件和目录名的列表(不包含 ...)。
  • os.scandir(path='.'): ​​(推荐)​​ 返回一个迭代器,包含 DirEntry 对象。它比 listdir 更高效,尤其是在需要获取文件属性(如大小、修改时间)时,因为它在扫描时直接获取这些信息,避免了额外的系统调用。
import os

# 使用 listdir
print("使用 os.listdir():")
for entry in os.listdir('.'):
    print(entry)

print("\n使用 os.scandir() (更强大):")
# 使用 scandir
with os.scandir('.') as entries:
    for entry in entries:
        info = f"{entry.name}"
        if entry.is_file():
            info += " (文件)"
        elif entry.is_dir():
            info += " (目录)"
        # 可以直接获取 stat 信息,无需额外调用 os.stat()
        info += f", 大小: {entry.stat().st_size} bytes"
        print(info)

4. 创建和删除目录

  • os.mkdir(path, mode=0o777): 创建单个目录。如果父目录不存在,会抛出 FileNotFoundError
  • os.makedirs(name, mode=0o777, exist_ok=False): 递归创建多层目录。相当于 Linux 命令 mkdir -p
    • exist_ok=True 时,如果目录已存在,不会报错。
  • os.rmdir(path): 删除目录。如果目录非空,会抛出 OSError
  • os.removedirs(name): 递归删除空目录。如果子目录被成功删除,removedirs() 会尝试依次删除父目录,直到遇到一个非空目录为止。
import os

# 创建目录
os.mkdir("new_folder") # 创建单个目录
os.makedirs("parent/child/grandchild", exist_ok=True) # 递归创建,且目录存在时不报错

# 删除目录
os.rmdir("new_folder") # 只能删除空目录
os.removedirs("parent/child/grandchild") # 递归删除空目录

5. 创建和删除文件

  • 创建文件​:通常使用内置的 open() 函数。
    • open('file.txt', 'w').close(): 创建一个空文件(如果文件已存在则清空)。
  • os.remove(path)os.unlink(path): 删除一个文件。如果路径是目录,则抛出 IsADirectoryError
import os

# 创建一个新文件
with open("temp_file.txt", "w") as f:
    f.write("Hello, World!")
print("文件已创建。")

# 删除文件
os.remove("temp_file.txt")
print("文件已删除。")

6. 重命名和移动文件/目录

  • os.rename(src, dst): 重命名文件或目录。如果 dst 是一个已存在的目录或文件,在某些系统上可能会失败。
  • os.replace(src, dst): 替换文件或目录。如果 dst 存在,它会被静默替换,这在跨平台时比 rename 更安全。
import os

# 创建源文件
with open("old_name.txt", "w") as f:
    f.write("待重命名的文件")

# 重命名/移动文件
os.rename("old_name.txt", "new_name.txt")
# 或者更安全的方式
# os.replace("old_name.txt", "new_name.txt")

print("文件已重命名。")

# 清理
os.remove("new_name.txt")

7. 检查路径状态和信息

  • os.path.exists(path): 判断路径是否存在。
  • os.path.isfile(path): 判断路径是否是文件。
  • os.path.isdir(path): 判断路径是否是目录。
  • os.path.islink(path): 判断路径是否是符号链接(symbolic link)。
  • os.path.getsize(path): 返回文件的大小(字节)。
  • os.path.getmtime(path): 返回文件的最后修改时间戳。
  • os.path.abspath(path): 返回路径的绝对路径。
  • os.path.basename(path): 返回路径的最后一部分(文件名或最后的目录名)。
  • os.path.dirname(path): 返回路径的目录部分。
  • os.path.split(path): 将路径分割为 (目录, 文件名) 的元组。
  • os.path.splitext(path): 将路径分割为 (文件名, 扩展名) 的元组。
import os
import time

file_path = "example.txt"

# 先确保文件存在
with open(file_path, "w") as f:
    f.write("Test content.")

# 检查状态
print(f"路径 '{file_path}' 存在吗? {os.path.exists(file_path)}")
print(f"它是一个文件吗? {os.path.isfile(file_path)}")
print(f"它是一个目录吗? {os.path.isdir(file_path)}")
print(f"文件大小: {os.path.getsize(file_path)} bytes")
print(f"最后修改时间: {time.ctime(os.path.getmtime(file_path))}")

# 路径操作
abs_path = os.path.abspath(file_path)
print(f"绝对路径: {abs_path}")

base_name = os.path.basename(abs_path)
dir_name = os.path.dirname(abs_path)
print(f"文件名: {base_name}, 所在目录: {dir_name}")

split_path = os.path.split(abs_path)
split_ext = os.path.splitext(base_name)
print(f"分割路径: {split_path}")
print(f"分割扩展名: {split_ext}")

# 清理
os.remove(file_path)

8. 遍历目录树:os.walk()

os.walk() 是一个强大的生成器,用于自上而下或自下而上遍历目录树。对于需要处理目录及其所有子目录中的文件的情况,它是完美的工具。

import os

# 打印当前目录及其所有子目录下的所有 .py 文件
for root, dirs, files in os.walk('.'):
    for file in files:
        if file.endswith('.py'):
            # root 是当前遍历到的目录路径
            # file 是该目录下的文件名
            full_path = os.path.join(root, file)
            print(full_path)

os.walk() 返回的每一项是 (root, dirs, files)

  • root:当前正在遍历的目录路径。
  • dirs:一个包含 root 中所有子目录名称的列表。
  • files:一个包含 root 中所有文件名称的列表。

9. 现代替代方案:pathlib 模块

虽然 os 模块功能强大,但从 Python 3.4 开始引入的 pathlib 模块提供了更现代、面向对象的方式来操作路径。它让路径操作变得更直观、更易读。

示例对比:​

任务使用 os.path使用 pathlib.Path
拼接路径os.path.join("a", "b", "c")Path("a") / "b" / "c"
获取文件名os.path.basename("/a/b/c.txt")Path("/a/b/c.txt").name
获取目录名os.path.dirname("/a/b/c.txt")Path("/a/b/c.txt").parent
检查是否存在os.path.exists("file.txt")Path("file.txt").exists()
读取文件with open(...)Path("file.txt").read_text()

简单示例:​

from pathlib import Path

# 创建 Path 对象
p = Path("my_folder") / "sub_folder" / "data.txt"

# 创建目录
p.parent.mkdir(parents=True, exist_ok=True)

# 写入文件
p.write_text("Hello from pathlib!")

# 读取文件
content = p.read_text()
print(content)

# 遍历所有 .txt 文件
for txt_file in Path(".").glob("**/*.txt"):
    print(txt_file)

# 清理
p.unlink() # 删除文件
p.parent.rmdir() # 删除空目录 (需要先确保 parent 为空)

建议​:对于新项目,​优先考虑使用 pathlib,因为它代码更简洁、可读性更高,并且能更好地处理不同操作系统的路径差异。但在维护旧代码或与不熟悉 pathlib 的团队协作时,os.path 仍然是可靠的选择。


最佳实践与安全提示

  1. ​**始终使用 os.path.join()pathlib**​:避免硬编码路径分隔符。
  2. 谨慎使用递归删除​:shutil.rmtree() 可以删除非空目录,但极其危险。在使用前务必进行二次确认。
  3. 处理异常​:文件操作经常因权限不足、路径不存在等原因失败。使用 try...except 块来处理 OSError, FileNotFoundError, PermissionError 等异常。
  4. 使用 with 语句​:操作文件时,始终使用 with open(...) as f: 语句,它能确保文件被正确关闭,即使在发生错误时也是如此。
  5. 注意跨平台兼容性​:在 Windows 上路径不区分大小写,而在 Linux/macOS 上区分。编写跨平台脚本时要特别注意这一点。
  6. ​**优先使用 scandirpathlib**​:它们在性能和易用性上通常优于旧的 listdiros.path 函数。

通过掌握本指南的内容,你将能够有效地使用 Python 的 os 模块来管理文件系统和执行各种操作系统相关的任务。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞89 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容