Python 中获取目录操作完全指南

1. 引言

在 Python 编程中,文件和目录操作是日常任务的基础。无论是读取配置文件、遍历日志文件,还是管理项目资源,都离不开对目录的获取和操作。Python 标准库提供了强大且易用的模块(如 ospathlib)来帮助我们完成这些任务。本文将系统介绍在 Python 中获取目录的各种方法,从基础路径操作到高级遍历技巧,并附上详细的代码示例,帮助你高效处理文件系统任务。

2. 核心模块概览

Python 提供了两个主要的模块来处理目录和路径:

  • os 模块 :传统的系统操作模块,提供了大量与操作系统交互的函数,如 os.listdir()os.walk() 等。
  • pathlib 模块(Python 3.4+ 引入):面向对象的路径操作库,提供了更直观、更 Pythonic 的 API,推荐在新项目中使用。

3. 获取当前工作目录

当前工作目录(Current Working Directory, CWD)是 Python 脚本执行时所在的目录。获取它是许多文件操作的第一步。

使用 os.getcwd()

python 复制代码
import os

current_dir = os.getcwd()
print(f"当前工作目录: {current_dir}")
# 输出示例: 当前工作目录: /home/user/projects

使用 pathlib.Path.cwd()

python 复制代码
from pathlib import Path

current_dir = Path.cwd()
print(f"当前工作目录: {current_dir}")
# 输出示例: 当前工作目录: /home/user/projects

区别os.getcwd() 返回字符串,Path.cwd() 返回一个 Path 对象,后者可以直接调用更多方法(如 .parent.joinpath())。

4. 列出目录内容

获取目录下的所有文件和子目录。

使用 os.listdir()

python 复制代码
import os

path = "./data"
try:
    entries = os.listdir(path)
    print(f"目录 '{path}' 下的内容:")
    for entry in entries:
        print(f"  - {entry}")
except FileNotFoundError:
    print(f"目录 '{path}' 不存在")

使用 pathlib.Path.iterdir()

python 复制代码
from pathlib import Path

path = Path("./data")
if path.exists() and path.is_dir():
    print(f"目录 '{path}' 下的内容:")
    for entry in path.iterdir():
        print(f"  - {entry.name}")  # entry 是一个 Path 对象
else:
    print(f"目录 '{path}' 不存在或不是目录")

注意os.listdir() 返回文件名(字符串)列表,而 path.iterdir() 返回 Path 对象生成器,后者可以更方便地获取文件属性。

5. 递归遍历目录树

当需要处理目录及其所有子目录时,递归遍历是必要的。

使用 os.walk()

os.walk() 是一个生成器,为每个目录返回一个三元组 (dirpath, dirnames, filenames)

python 复制代码
import os

root_dir = "./project"
for dirpath, dirnames, filenames in os.walk(root_dir):
    print(f"正在访问目录: {dirpath}")
    print(f"  子目录: {dirnames}")
    print(f"  文件: {filenames}")
    print("-" * 40)

使用 pathlib.Path.rglob()glob()

Path.rglob(pattern) 递归匹配模式,Path.glob(pattern) 仅在当前目录匹配。

python 复制代码
from pathlib import Path

# 递归查找所有 .py 文件
project_path = Path("./project")
py_files = list(project_path.rglob("*.py"))
print("所有 Python 文件:")
for py_file in py_files:
    print(f"  - {py_file}")

# 仅在当前目录查找 .txt 文件
txt_files = list(project_path.glob("*.txt"))
print("\n当前目录下的文本文件:")
for txt_file in txt_files:
    print(f"  - {txt_file}")

6. 获取目录的绝对路径

绝对路径是从根目录开始的完整路径,在不同环境下更可靠。

使用 os.path.abspath()

python 复制代码
import os

relative_path = "./docs/readme.txt"
absolute_path = os.path.abspath(relative_path)
print(f"相对路径: {relative_path}")
print(f"绝对路径: {absolute_path}")

使用 pathlib.Path.resolve()

resolve() 方法会解析符号链接并返回绝对路径。

python 复制代码
from pathlib import Path

relative_path = Path("./docs/readme.txt")
absolute_path = relative_path.resolve()
print(f"绝对路径: {absolute_path}")

7. 检查路径是否为目录

在操作前,最好先确认路径指向的是目录。

python 复制代码
import os
from pathlib import Path

path_str = "./src"
path_obj = Path(path_str)

# 使用 os.path.isdir
if os.path.isdir(path_str):
    print(f"'{path_str}' 是一个目录 (os)")

# 使用 Path.is_dir()
if path_obj.is_dir():
    print(f"'{path_str}' 是一个目录 (pathlib)")

8. 创建与删除目录

创建目录

python 复制代码
import os
from pathlib import Path

# 创建单个目录
os.makedirs("./new_dir", exist_ok=True)  # exist_ok=True 避免目录已存在时报错
Path("./another_dir").mkdir(exist_ok=True)

# 创建多级目录(递归创建)
os.makedirs("./parent/child/grandchild", exist_ok=True)
Path("./deep/nested/path").mkdir(parents=True, exist_ok=True)

删除目录

python 复制代码
import shutil
from pathlib import Path

# 删除空目录
try:
    os.rmdir("./empty_dir")
except OSError as e:
    print(f"删除失败: {e}")

# 删除非空目录(递归删除,危险!)
shutil.rmtree("./dir_with_content", ignore_errors=True)

# 使用 pathlib (需配合 shutil 删除非空目录)
target_dir = Path("./to_delete")
if target_dir.exists():
    if target_dir.is_dir():
        shutil.rmtree(target_dir)

9. 路径拼接与分解

安全地组合和拆分路径,避免手动字符串拼接。

使用 os.path.join()

python 复制代码
import os

base = "/home/user"
subdir = "docs"
filename = "file.txt"

full_path = os.path.join(base, subdir, filename)
print(f"完整路径: {full_path}")
# 输出: /home/user/docs/file.txt

使用 pathlib.Path/ 操作符

python 复制代码
from pathlib import Path

base = Path("/home/user")
full_path = base / "docs" / "file.txt"
print(f"完整路径: {full_path}")
# 输出: /home/user/docs/file.txt

# 获取父目录、文件名、后缀等
print(f"父目录: {full_path.parent}")
print(f"文件名: {full_path.name}")
print(f"后缀: {full_path.suffix}")
print(f"无后缀的文件名: {full_path.stem}")

10. 实战示例:统计目录下文件类型

结合以上知识,实现一个统计目录下各类文件数量的脚本。

python 复制代码
from pathlib import Path
from collections import Counter

def analyze_directory(directory_path):
    """分析目录下文件的类型分布"""
    path = Path(directory_path)
    if not path.exists() or not path.is_dir():
        print(f"错误: '{directory_path}' 不是有效目录")
        return

    extensions = []
    for item in path.rglob("*"):  # 递归遍历所有文件
        if item.is_file():
            ext = item.suffix.lower() or "无后缀"
            extensions.append(ext)

    if not extensions:
        print("该目录下未找到文件。")
        return

    counter = Counter(extensions)
    print(f"目录 '{directory_path}' 下的文件类型统计:")
    for ext, count in counter.most_common():
        print(f"  {ext}: {count} 个文件")

# 使用示例
analyze_directory("./my_project")

11. 总结与最佳实践

  1. 优先使用 pathlib :对于新项目,pathlib 提供了更清晰、更安全的 API。
  2. 处理异常 :文件系统操作可能失败(如权限不足、路径不存在),务必使用 try...except
  3. 使用绝对路径:在脚本中处理关键路径时,使用绝对路径可以避免因工作目录变化导致的错误。
  4. 递归操作需谨慎 :使用 shutil.rmtree()rglob() 时,确保目标路径正确,避免误删。
  5. 跨平台兼容性 :使用 os.path.join()pathlib 的路径操作符可以确保路径分隔符在不同操作系统(Windows/Linux/macOS)上正确工作。

通过掌握这些方法,你可以轻松地在 Python 中完成各种目录获取和操作任务,为更复杂的文件处理工作打下坚实基础。

相关推荐
南京云森杉木桩1 小时前
常见打桩木品牌推荐,选对材质让工程更稳固
人工智能·python·材质
总有刁民想爱朕ha1 小时前
Python PyQt5图片批量转MP4视频工具:本地离线免费无水印,完整代码
开发语言·python·qt
zyj8890911 小时前
濮阳工厂目视化设计安全警示牌材质怎么选耐用
python·安全·材质
雾沉川1 小时前
d3dx9_43.dll 丢失报错原因分析及三种标准修复方法
microsoft·3d
宸津-代码粉碎机2 小时前
FastUtil+AI多Agent实战:Java AI项目性能终极加速方案
java·服务器·开发语言·python·安全·php
for_ever_love__2 小时前
python基础语法学习: 装饰器
python·学习·装饰器·装饰器模式
Python私教2 小时前
Python 3.15 来了:free-threading 稳定 ABI 能给高并发服务带来什么
开发语言·python
tju新生代魔迷2 小时前
Python学习日记2
python·学习
Zane19943 小时前
create_task 和直接 await 到底有什么不一样?asyncio 的 Task、gather 与并发数量控制
后端·python