一、什么是文件路径?
文件路径是文件在计算机文件系统中的唯一位置标识。它告诉操作系统如何找到和访问存储在磁盘上的特定文件或目录。
1. 路径的作用
# 路径告诉 Python 去哪里找文件# 就像地址告诉快递员去哪里送包裹# 例如,要读取一个配置文件# 我们需要告诉 Python 这个文件在哪里file_path = "/home/user/config.txt" # Linux/Mac# 或file_path = "C:\\Users\\user\\config.txt" # Windows
二、绝对路径 vs 相对路径
1. 绝对路径(Absolute Path)
绝对路径是从根目录开始的完整路径,唯一标识一个文件或目录。
import osfrom pathlib import Path# 绝对路径示例windows_path = "C:\\Users\\John\\Documents\\file.txt" # Windowslinux_path = "/home/john/documents/file.txt" # Linux/Mac# 获取当前文件的绝对路径current_file = __file__abs_path = os.path.abspath(current_file)print(f"绝对路径: {abs_path}")# 获取当前工作目录的绝对路径current_dir = os.getcwd()print(f"当前目录绝对路径: {current_dir}")# 使用 pathlib 获取绝对路径path_obj = Path("data.txt")print(f"绝对路径: {path_obj.resolve()}")
2. 相对路径(Relative Path)
相对路径是相对于当前工作目录(Current Working Directory)的路径。
import os# 相对路径示例current_dir = os.getcwd()print(f"当前目录: {current_dir}")# 当前目录下的文件file1 = "data.txt" # 当前目录file2 = "./data.txt" # 当前目录(./ 表示当前目录)file3 = "./docs/readme.txt" # 当前目录下的 docs 文件夹中file4 = "../parent/file.txt" # 上一级目录(../ 表示上一级)file5 = "../../grandparent/file.txt" # 上两级目录
3. 路径对比示例
import osfrom pathlib import Path# 假设项目结构# project/# ├── main.py# ├── data/# │ └── users.csv# └── utils/# └── helper.py# 在 main.py 中current_dir = os.getcwd()print(f"当前工作目录: {current_dir}")# 绝对路径(从根目录开始)abs_data_path = "/home/user/project/data/users.csv"print(f"绝对路径: {abs_data_path}")# 相对路径(相对于当前文件)rel_data_path = "data/users.csv" # 相对于 main.pyprint(f"相对路径: {rel_data_path}")# 使用相对路径读取文件with open("data/users.csv", 'r') as f: content = f.read()
三、不同操作系统的路径格式
1. Windows 路径格式
import os# Windows 使用反斜杠(\)作为分隔符# 注意:反斜杠在 Python 中是转义字符,需要特殊处理# 方法1:使用双反斜杠转义windows_path1 = "C:\\Users\\John\\file.txt"# 方法2:使用原始字符串(推荐)windows_path2 = r"C:\Users\John\file.txt"# 方法3:使用正斜杠(Python 也支持)windows_path3 = "C:/Users/John/file.txt"# 使用 os.path 处理 Windows 路径path = r"C:\Users\John\Documents\file.txt"print(f"目录: {os.path.dirname(path)}")print(f"文件名: {os.path.basename(path)}")
2. Linux/Mac 路径格式
import os# Linux/Mac 使用正斜杠(/)作为分隔符linux_path = "/home/user/documents/file.txt"mac_path = "/Users/john/Documents/file.txt"# 使用 os.path 处理路径path = "/home/user/documents/file.txt"print(f"目录: {os.path.dirname(path)}")print(f"文件名: {os.path.basename(path)}")
3. 跨平台路径处理(核心知识点)
import osfrom pathlib import Path# 方法1:使用 os.path.join(跨平台推荐)path = os.path.join("folder", "subfolder", "file.txt")print(f"os.path.join: {path}")# Windows: folder\subfolder\file.txt# Linux: folder/subfolder/file.txt# 方法2:使用 pathlib(现代推荐)path = Path("folder") / "subfolder" / "file.txt"print(f"pathlib: {path}")# 方法3:使用原始字符串(手动处理,不推荐)windows_path = r"folder\subfolder\file.txt" # 仅 Windowslinux_path = "folder/subfolder/file.txt" # 仅 Linux
四、路径的组成部分
1. 路径解析(os.path 方式)
import os# 示例路径file_path = "/home/user/projects/data/config.json"print("=== 使用 os.path 分解 ===")print(f"完整路径: {file_path}")print(f"目录: {os.path.dirname(file_path)}")print(f"文件名: {os.path.basename(file_path)}")print(f"扩展名: {os.path.splitext(file_path)[1]}")print(f"文件名(无扩展名): {os.path.splitext(file_path)[0]}")
2. 路径解析(pathlib 方式 - 推荐)
from pathlib import Path# 示例路径file_path = "/home/user/projects/data/config.json"path_obj = Path(file_path)print("=== 使用 pathlib 分解 ===")print(f"完整路径: {path_obj}")print(f"父目录: {path_obj.parent}")print(f"文件名: {path_obj.name}")print(f"扩展名: {path_obj.suffix}")print(f"文件名(无扩展名): {path_obj.stem}")
3. 路径的所有部分
from pathlib import Pathpath = Path("/home/user/docs/2024/report.pdf")print("=== 路径详细分解 ===")print(f"根目录: {path.anchor}") # Windows: C:\ Linux: /print(f"父目录: {path.parent}") # /home/user/docs/2024print(f"所有父目录: {list(path.parents)}") # [Path('/home/user/docs/2024'), Path('/home/user/docs'), ...]print(f"路径部分: {path.parts}") # ('/', 'home', 'user', 'docs', '2024', 'report.pdf')print(f"文件名: {path.name}") # report.pdfprint(f"文件名(无后缀): {path.stem}") # reportprint(f"后缀: {path.suffix}") # .pdfprint(f"所有后缀: {path.suffixes}") # ['.pdf']# 处理多个后缀的文件path2 = Path("archive.tar.gz")print(f"文件名: {path2.name}") # archive.tar.gzprint(f"stem: {path2.stem}") # archive.tar(只去掉最后一个后缀)print(f"suffixes: {path2.suffixes}") # ['.tar', '.gz']
五、基础路径操作
1. 路径拼接
import osfrom pathlib import Pathbase_dir = "/home/user"filename = "data.txt"# 方法1:使用 os.path.join(传统方式)path1 = os.path.join(base_dir, "docs", filename)print(f"os.path.join: {path1}")# 方法2:使用 pathlib(推荐方式)path2 = Path(base_dir) / "docs" / filenameprint(f"pathlib: {path2}")# 方法3:使用格式化字符串(不推荐,跨平台问题)# path3 = f"{base_dir}/docs/{filename}" # 仅适用于 Linux/Mac
2. 路径规范化
import osfrom pathlib import Path# 处理冗余分隔符和相对路径messy_path = "./docs//reports/../data/./file.txt"# 使用 os.path.normpathnormalized = os.path.normpath(messy_path)print(f"规范化后: {normalized}")# 输出: docs/data/file.txt# 转换为绝对路径abs_path = os.path.abspath(messy_path)print(f"绝对路径: {abs_path}")# 使用 pathlib(推荐)path_obj = Path(messy_path).resolve()print(f"pathlib resolve: {path_obj}")
3. 路径有效性检查
import osfrom pathlib import Pathpath = "/home/user/file.txt"print("=== 检查路径存在性 ===")print(f"路径存在: {os.path.exists(path)}")print(f"Path 存在: {Path(path).exists()}")print("\n=== 检查文件/目录类型 ===")print(f"是文件: {os.path.isfile(path)}")print(f"Path 是文件: {Path(path).is_file()}")print(f"是目录: {os.path.isdir(path)}")print(f"Path 是目录: {Path(path).is_dir()}")print("\n=== 检查路径类型 ===")print(f"是绝对路径: {os.path.isabs(path)}")print(f"Path 是绝对路径: {Path(path).is_absolute()}")# 检查文件大小if os.path.exists(path): size = os.path.getsize(path) print(f"文件大小: {size} 字节")
六、获取常用系统路径
1. 获取当前工作目录
import osfrom pathlib import Path# 方式1:使用 os.getcwd()current_dir = os.getcwd()print(f"当前工作目录: {current_dir}")# 方式2:使用 pathlibcurrent_dir = Path.cwd()print(f"pathlib 当前目录: {current_dir}")# 切换工作目录os.chdir("/tmp")print(f"切换后目录: {os.getcwd()}")# 切换回原目录(使用上下文管理器更安全)from contextlib import contextmanager@contextmanagerdef change_directory(path): """临时切换目录的上下文管理器""" original_dir = os.getcwd() try: os.chdir(path) yield finally: os.chdir(original_dir)with change_directory("/tmp"): print(f"临时目录: {os.getcwd()}") # 执行临时目录下的操作print(f"恢复目录: {os.getcwd()}")
2. 获取脚本所在目录
import osfrom pathlib import Path# 重要:获取当前脚本文件所在目录# 这是最常用的路径操作之一# 方法1:使用 os.pathscript_dir = os.path.dirname(os.path.abspath(__file__))print(f"脚本目录 (os): {script_dir}")# 方法2:使用 pathlib(推荐)script_dir = Path(__file__).parentprint(f"脚本目录 (pathlib): {script_dir}")# 获取脚本的绝对路径script_path = Path(__file__).resolve()print(f"脚本绝对路径: {script_path}")# 获取脚本文件名script_name = Path(__file__).nameprint(f"脚本文件名: {script_name}")
3. 获取用户系统目录
import osfrom pathlib import Pathimport sysdef get_user_directories(): """获取常用用户目录""" # 用户主目录 home = Path.home() print(f"用户主目录: {home}") # 当前工作目录 cwd = Path.cwd() print(f"当前目录: {cwd}") # 临时目录 temp = Path(os.environ.get('TEMP', '/tmp')) print(f"临时目录: {temp}") # 桌面目录(跨平台) if sys.platform == 'win32': import winreg key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders') desktop = winreg.QueryValueEx(key, 'Desktop')[0] desktop = Path(desktop) else: desktop = home / 'Desktop' print(f"桌面目录: {desktop}") # 文档目录 if sys.platform == 'win32': import winreg key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders') documents = winreg.QueryValueEx(key, 'Personal')[0] documents = Path(documents) else: documents = home / 'Documents' print(f"文档目录: {documents}") return { 'home': home, 'cwd': cwd, 'temp': temp, 'desktop': desktop, 'documents': documents }# 使用示例dirs = get_user_directories()
📝 学习检查清单
理解什么是文件路径及其作用
掌握绝对路径和相对路径的区别
了解 Windows 和 Linux/Mac 路径格式的差异
能够使用 os.path.join 进行跨平台路径拼接
掌握 pathlib 模块的基本使用
能够分解路径的各个组成部分(目录、文件名、扩展名)
能够检查路径的有效性(存在、类型等)
会获取当前工作目录和脚本所在目录