专为 config.py 中
ROOT_DIR等路径配置而写
1. 获取项目根目录(ROOT_DIR)
推荐写法
from pathlib import Path
# 方法1:基于当前文件位置(最常用)
# 假设 config.py 在 scripts/ 目录下
ROOT_DIR = Path(__file__).parent.parent # 上两级目录
# 方法2:基于工作目录
import os
ROOT_DIR = Path(os.getcwd())
# 方法3:固定路径(不推荐,换电脑会坏)
ROOT_DIR = Path("C:/Users/xxx/project") # ❌ 别这样
图解 __file__ 的 parent
项目目录/
├── scripts/
│ └── config.py ← __file__ 在这里
├── watch/
├── extracted/
└── ...
Path(__file__) = 项目目录/scripts/config.py
Path(__file__).parent = 项目目录/scripts
Path(__file__).parent.parent = 项目目录 ← ROOT_DIR
2. 构建其他路径
传统字符串方式(麻烦)
import os
# 字符串拼接,要考虑 / 和 \
watch_dir = os.path.join(ROOT_DIR, "watch")
extract_dir = os.path.join(ROOT_DIR, "extracted")
# 还要手动创建目录
os.makedirs(watch_dir, exist_ok=True)
pathlib 方式(简洁)
from pathlib import Path
ROOT_DIR = Path(__file__).parent.parent
# 用 / 直接拼接路径
WATCH_DIR = ROOT_DIR / "watch"
EXTRACT_DIR = ROOT_DIR / "extracted"
COMPRESSED_DIR = ROOT_DIR / "compressed"
# 自动创建目录(包括父目录)
WATCH_DIR.mkdir(parents=True, exist_ok=True)
更多拼接示例
base = Path("/home/user/project")
# 拼接子目录
subdir = base / "data" / "2024" # /home/user/project/data/2024
# 拼接文件
file = base / "config" / "settings.json" # /home/user/project/config/settings.json
# 在 config.py 中的实际应用
PATHS = {
"watch": ROOT_DIR / "watch",
"extracted": ROOT_DIR / "extracted",
"compressed": ROOT_DIR / "compressed",
}
3. 常用操作速查表
| 操作 | 代码 | 结果 |
|---|---|---|
| 获取文件名 | Path("/a/b/c.txt").name | c.txt |
| 获取后缀 | Path("/a/b/c.txt").suffix | .txt |
| 获取纯名 | Path("/a/b/c.txt").stem | c |
| 获取父目录 | Path("/a/b/c.txt").parent | /a/b |
| 改后缀 | Path("c.txt").with_suffix(".jpg") | c.jpg |
| 绝对路径 | Path("./file").resolve() | 完整路径 |
| 是否存在 | Path("/a/b").exists() | True/False |
| 是文件 | Path("/a/b").is_file() | True/False |
| 是目录 | Path("/a/b").is_dir() | True/False |
4. 遍历目录
from pathlib import Path
root = Path("./watch")
# 遍历所有文件和子目录
for item in root.iterdir():
print(item) # 可能是文件或目录
# 只遍历文件
for file in root.iterdir():
if file.is_file():
print(f"文件: {file.name}")
# 只遍历 .jpg 文件
for jpg in root.glob("*.jpg"):
print(jpg)
# 递归遍历所有图片(包括子目录)
for img in root.rglob("*.jpg"): # rglob = recursive glob
print(img)
5. 实际应用场景
场景1:config.py 中的路径配置
from pathlib import Path
# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent
# 各种路径
PATHS = {
"watch": PROJECT_ROOT / "watch",
"extracted": PROJECT_ROOT / "extracted",
"compressed": PROJECT_ROOT / "compressed",
"archived": PROJECT_ROOT / "archived",
"logs": PROJECT_ROOT / "logs",
}
# 确保目录都存在
for name, path in PATHS.items():
path.mkdir(parents=True, exist_ok=True)
print(f"✓ {name}: {path}")
场景2:检查文件类型
from pathlib import Path
from config import ALLOWED_IMAGE_EXTS
def is_allowed_image(file_path: Path) -> bool:
"""检查是否是允许的图片格式"""
return file_path.suffix.lower() in ALLOWED_IMAGE_EXTS
# 使用
file = Path("photo.JPG")
if is_allowed_image(file):
print("是合法图片")
场景3:批量重命名
from pathlib import Path
def batch_rename(directory: Path, old_ext: str, new_ext: str):
"""批量修改文件后缀"""
for file in directory.glob(f"*{old_ext}"):
new_name = file.with_suffix(new_ext)
file.rename(new_name)
print(f"{file.name} -> {new_name.name}")
# 使用
batch_rename(Path("./images"), ".jpeg", ".jpg")
6. 常见错误
错误1:混用字符串和 Path
from pathlib import Path
root = Path("./project")
# 错!不能直接用 +
# path = root + "/subdir" # ❌ 报错
# 对!用 /
path = root / "subdir" # ✅
错误2:忘记转换传给旧 API
from pathlib import Path
import os
p = Path("./test.txt")
# 一些旧库只接受字符串
# os.system(f"cat {p}") # 可能有问题
# 转字符串
os.system(f"cat {str(p)}") # ✅
# 或
os.system(f"cat {p.as_posix()}") # ✅ 用正斜杠
错误3:Windows 下的反斜杠
from pathlib import Path
p = Path("C:/Users/name/file.txt")
print(p) # C:\Users\name\file.txt (Windows 自动转)
print(str(p)) # C:\Users\name\file.txt
print(p.as_posix()) # C:/Users/name/file.txt (正斜杠,用于 URL)
7. 对比:os.path vs pathlib
| 操作 | os.path (旧) | pathlib (新) |
|---|---|---|
| 拼接路径 | os.path.join(a, b) | a / b |
| 获取文件名 | os.path.basename(p) | p.name |
| 获取目录 | os.path.dirname(p) | p.parent |
| 获取后缀 | os.path.splitext(p)[1] | p.suffix |
| 绝对路径 | os.path.abspath(p) | p.resolve() |
| 是否存在 | os.path.exists(p) | p.exists() |
| 创建目录 | os.makedirs(p) | p.mkdir(parents=True) |
结论:新项目直接用 pathlib,更面向对象、更易读。
8. 给你的 config.py 模板
"""
配置文件
"""
from pathlib import Path
# ==================== 基础路径 ====================
# 项目根目录:config.py 在 scripts/ 下,所以上两级是根目录
PROJECT_ROOT = Path(__file__).parent.parent
# ==================== 各阶段目录 ====================
PATHS = {
"watch": PROJECT_ROOT / "watch", # 监听文件夹
"extracted": PROJECT_ROOT / "extracted", # 解压目录
"compressed": PROJECT_ROOT / "compressed", # 压缩后图片
"archived": PROJECT_ROOT / "archived", # 最终分卷压缩
"logs": PROJECT_ROOT / "logs", # 日志目录
}
# ==================== 辅助函数 ====================
def ensure_dirs():
"""确保所有目录都存在"""
for path in PATHS.values():
path.mkdir(parents=True, exist_ok=True)
# 测试
if __name__ == "__main__":
ensure_dirs()
for name, path in PATHS.items():
print(f"{name}: {path}")
参考
- Python 官方文档:https://docs.python.org/3/library/pathlib.html
- 建议 Python 版本:3.6+(pathlib 已完善)