Logo
Published on

3.8.文件路径

Authors
  • avatar
    Name
    xiaobai
    Twitter

1.概述

Python 提供了强大的文件路径操作功能,主要使用 os.path 模块和 pathlib 模块。掌握路径操作对于文件管理、数据处理和跨平台开发至关重要。

2.核心概念

  • 路径:指向文件或目录的字符串或对象
  • 绝对路径:从根目录开始的完整路径
  • 相对路径:相对于当前工作目录的路径
  • 跨平台:不同操作系统使用不同的路径分隔符

3.导入必要模块

import os                    # 操作系统接口
import os.path              # 传统路径操作
from pathlib import Path    # 现代路径操作(推荐)
import glob                 # 文件通配符搜索
import shutil               # 高级文件操作

4.os.path 模块 - 传统路径操作

4.1.路径拼接和分解

4.1.1.路径拼接

使用 os.path.join() 自动处理不同操作系统的路径分隔符:

import os

# 路径拼接 - 自动处理分隔符
full_path = os.path.join('父文件夹', '子文件夹', '文件.txt')
print(full_path)  # Linux/Mac: 父文件夹/子文件夹/文件.txt
                  # Windows: 父文件夹\子文件夹\文件.txt

4.1.2.获取文件名和目录名

import os

path = '/home/user/documents/file.txt'

# 获取文件名
print(os.path.basename(path))  # file.txt

# 获取目录名
print(os.path.dirname(path))   # /home/user/documents

# 分割路径
print(os.path.split(path))     # ('/home/user/documents', 'file.txt')

4.1.3.分离扩展名

import os

# 分离文件名和扩展名
name, ext = os.path.splitext('example.tar.gz')
print(name)  # example.tar
print(ext)   # .gz

4.1.4.获取绝对路径

import os

# 获取绝对路径
print(os.path.abspath('file.txt'))   # 不解析符号链接
print(os.path.realpath('file.txt'))  # 解析符号链接

4.2.路径检查和属性

函数描述返回值
os.path.exists()检查路径是否存在True/False
os.path.isfile()检查是否为文件True/False
os.path.isdir()检查是否为目录True/False
os.path.islink()检查是否为符号链接True/False
os.path.getsize()获取文件大小字节数
os.path.getmtime()获取最后修改时间时间戳
os.path.getatime()获取最后访问时间时间戳
import os

path = '/home/user/documents'

# 检查路径属性
print(os.path.exists(path))      # True/False
print(os.path.isfile(path))      # True/False
print(os.path.isdir(path))       # True/False
print(os.path.islink(path))      # True/False

# 获取文件信息
if os.path.isfile(path):
    print(f"文件大小: {os.path.getsize(path)} 字节")
    print(f"修改时间: {os.path.getmtime(path)}")

5.pathlib 模块 - 现代路径操作(推荐)

pathlib 是 Python 3.4+ 引入的现代路径操作模块,提供面向对象的接口,更加直观和易用。

5.1.创建路径对象

from pathlib import Path

# 创建路径对象
path1 = Path('/home/user/documents')  # 绝对路径
path2 = Path('relative/path')         # 相对路径
path3 = Path.cwd()                    # 当前工作目录
path4 = Path.home()                   # 用户主目录

print(f"绝对路径: {path1}")
print(f"当前目录: {path3}")
print(f"用户主目录: {path4}")

5.2.路径对象优势

  • 面向对象:更直观的 API 设计
  • 跨平台:自动处理路径分隔符
  • 链式操作:支持方法链式调用
  • 类型安全:更好的类型提示支持

5.3.路径属性和方法

5.3.1.基本属性

from pathlib import Path

p = Path('/home/user/example/file.txt')

# 路径组成部分
print(f"完整路径: {p}")           # /home/user/example/file.txt
print(f"文件名: {p.name}")        # file.txt
print(f"文件名(无后缀): {p.stem}") # file
print(f"扩展名: {p.suffix}")      # .txt
print(f"父路径: {p.parent}")      # /home/user/example
print(f"磁盘/锚: {p.anchor}")     # Linux: /, Windows: C:\

5.3.2.路径修改

# 路径修改方法
print(f"替换文件名: {p.with_name('data.csv')}")    # /home/user/example/data.csv
print(f"替换扩展名: {p.with_suffix('.md')}")      # /home/user/example/file.md

5.3.3.路径检查

# 基本检查
print(f"是否存在: {p.exists()}")
print(f"是否为文件: {p.is_file()}")
print(f"是否为目录: {p.is_dir()}")
print(f"是否为绝对路径: {p.is_absolute()}")
print(f"绝对路径: {p.resolve()}")

5.3.4.安全获取文件信息

# 安全地获取文件信息
if p.is_file():
    stat = p.stat()
    print(f"文件大小: {stat.st_size} 字节")
    print(f"最后修改: {stat.st_mtime}")
else:
    print("不是文件,无法获取大小和时间")

5.4.路径遍历和文件操作

5.4.1.目录遍历

from pathlib import Path

folder = Path('src')

# 遍历目录内容(非递归)
for item in folder.iterdir():
    print(item)

# 使用通配符查找文件
for py_file in folder.glob('*.py'):
    print(py_file)

# 递归查找文件
for py_file in folder.rglob('*.py'):
    print(py_file)

5.4.2.目录创建

# 创建单个目录
new_folder = Path('new_directory')
new_folder.mkdir(exist_ok=True)  # 已存在不报错

# 创建多级目录
deep_folder = Path('level1/level2/level3')
deep_folder.mkdir(parents=True, exist_ok=True)

5.4.3.常用遍历方法

方法描述递归
iterdir()列出目录内容
glob(pattern)通配符查找
rglob(pattern)递归查找

5.4.4.通配符模式

  • *:匹配任意多个字符
  • ?:匹配单个字符
  • **:递归匹配(仅在 rglob 中有效)

6.常用路径操作示例

6.1.获取当前目录信息

import os
from pathlib import Path

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

# 使用 pathlib 获取当前目录
current_path = Path.cwd()  # 返回 Path 对象
print(f"当前路径: {current_path}")

# 获取用户主目录
home_dir = Path.home()
print(f"用户主目录: {home_dir}")

6.2.路径规范化

from pathlib import Path

# 处理相对路径和符号链接
path = Path('../../Documents/../file.txt')
print(f"原始路径: {path}")
print(f"解析后路径: {path.resolve()}")

# 计算相对路径
base_path = Path('/home/user/documents')
target_path = Path('/home/user/documents/work/project/file.txt')
relative_path = target_path.relative_to(base_path)
print(f"相对路径: {relative_path}")  # work/project/file.txt

6.3.文件路径操作综合示例

from pathlib import Path

# 定义多种路径示例
paths = [
    '/home/user/documents/report.pdf',
    'relative/path/file.txt',
    '../parent/file.py',
    'file_no_extension',
    'archive.tar.gz'
]

# 分析每个路径
for path_str in paths:
    path = Path(path_str)
    print(f"\n分析路径: {path}")
    print(f"文件名: {path.name}")
    print(f"主干名: {path.stem}")
    print(f"扩展名: {path.suffix}")
    print(f"父目录: {path.parent}")
    print(f"是否为绝对路径: {path.is_absolute()}")

6.4.输出结果示例

分析路径: /home/user/documents/report.pdf
文件名: report.pdf
主干名: report
扩展名: .pdf
父目录: /home/user/documents
是否为绝对路径: True

分析路径: relative/path/file.txt
文件名: file.txt
主干名: file
扩展名: .txt
父目录: relative/path
是否为绝对路径: False

7.文件和目录操作

7.1.文件操作

使用 pathlib 进行文件操作更加简洁和安全:

from pathlib import Path

# 创建文件并写入内容
file_path = Path('test.txt')
file_path.write_text('Hello, World!', encoding='utf-8')

# 读取文件内容
content = file_path.read_text(encoding='utf-8')
print(content)

# 获取文件信息
if file_path.exists():
    stat = file_path.stat()
    print(f"文件大小: {stat.st_size} 字节")
    print(f"最后修改: {stat.st_mtime}")

# 重命名文件
new_path = file_path.rename('new_test.txt')

7.2.文件操作优势

  • 简洁性:一行代码完成文件读写
  • 安全性:自动处理编码和异常
  • 跨平台:自动处理路径分隔符
  • 类型安全:更好的错误提示

7.3.目录操作

7.3.1.创建目录

from pathlib import Path
import shutil

# 创建单个目录
Path('example_dir').mkdir(exist_ok=True)

# 创建多级目录
Path('parent/child/grandchild').mkdir(parents=True, exist_ok=True)

7.3.2.遍历目录

# 遍历目录内容
folder = Path('example_dir')
print("目录内容:")
for item in folder.iterdir():
    if item.is_dir():
        print(f"目录: {item.name}")
    else:
        print(f"文件: {item.name}")

7.3.3.目录复制和删除

# 复制整个目录
shutil.copytree('example_dir', 'copy_dir', dirs_exist_ok=True)

# 删除空目录
Path('empty_dir').mkdir(exist_ok=True)
Path('empty_dir').rmdir()

# 删除非空目录
shutil.rmtree('copy_dir')

7.4.目录操作优势

  • 安全性exist_ok=True 避免重复创建错误
  • 递归性parents=True 自动创建父目录
  • 完整性shutil 提供完整的目录操作
  • 跨平台:自动处理不同操作系统的差异

8.跨平台路径处理

8.1.操作系统检测

from pathlib import Path
import os

# 根据操作系统选择路径
if os.name == 'nt':  # Windows
    path = Path('C:/Users/Name/Documents')
else:  # Unix/Linux/Mac
    path = Path('/home/name/documents')

# 路径拼接
file_path = path / 'subfolder' / 'file.txt'
print(f"文件路径: {file_path}")

# 转换为字符串
path_str = str(file_path)
print(f"字符串路径: {path_str}")

8.2.跨平台优势

  • 自动分隔符pathlib 自动处理 /\
  • 路径标准化:统一路径表示方式
  • 兼容性:代码在不同系统上都能正常工作
  • 类型安全:Path 对象提供更好的类型提示

9.实用函数示例

9.1.文件查找函数

from pathlib import Path

def find_files_by_extension(directory, extension):
    """查找指定目录下指定扩展名的所有文件"""
    directory_path = Path(directory)
    return list(directory_path.rglob(f'*{extension}'))

# 使用示例
python_files = find_files_by_extension('.', '.py')
print("找到的 Python 文件:")
for file in python_files:
    print(f"  {file}")

9.2.文件信息获取函数

def get_file_info(file_path):
    """获取文件的详细信息"""
    path = Path(file_path)
    if path.exists() and path.is_file():
        stat = path.stat()
        return {
            'name': path.name,
            'size': stat.st_size,
            'modified': stat.st_mtime,
            'absolute_path': str(path.absolute())
        }
    return None

# 使用示例
if python_files:
    file_info = get_file_info(python_files[0])
    print(f"文件信息: {file_info}")

9.3.文件备份函数

import shutil

def create_backup(file_path):
    """创建文件备份"""
    path = Path(file_path)
    if path.exists() and path.is_file():
        backup_path = path.with_suffix('.bak')
        shutil.copy2(path, backup_path)
        return backup_path
    return None

# 使用示例
backup_file = create_backup('example.txt')
if backup_file:
    print(f"备份文件: {backup_file}")

9.4.实用函数优势

  • 模块化:每个函数专注单一功能
  • 可重用:可以在不同项目中重复使用
  • 错误处理:包含适当的错误检查
  • 类型安全:使用 Path 对象提供更好的类型支持

10.最佳实践

10.1.路径操作原则

  1. 使用 pathlib:新项目推荐使用 pathlib,更现代、更直观
  2. 路径分隔符:使用 /os.path.join(),避免直接使用 \
  3. 路径检查:操作前检查路径是否存在
  4. 异常处理:使用 try-except 处理路径操作错误
  5. 跨平台兼容:确保代码在不同操作系统上都能正常工作

10.2.性能优化建议

  • 缓存路径对象:避免重复创建 Path 对象
  • 批量操作:使用 globrglob 进行批量文件操作
  • 路径规范化:使用 resolve() 获取规范路径
  • 内存管理:及时释放不需要的路径对象

10.3.安全注意事项

  • 路径验证:验证用户输入的路径
  • 权限检查:确保有足够的文件操作权限
  • 符号链接:注意符号链接可能带来的安全风险
  • 路径遍历:防止路径遍历攻击
img