match语句不能直接处理文件系统操作,需先用pathlib或os获取文件路径,再对file.suffix等属性进行模式匹配;它仅支持单值匹配,不支持批量操作或函数调用,且需注意大小写、复合后缀及并发安全。

match语句不能直接处理文件系统操作
Python的match语句只是语法糖,用于结构化模式匹配,它本身不读取文件、不遍历目录、也不移动或重命名文件。你得先用os.listdir()、pathlib.Path.iterdir()或glob拿到文件路径,再对每个文件的suffix、stem或name做匹配。
按后缀名分类文件的典型match写法
最常见需求是根据扩展名把文件归到不同目录。注意match只能作用于单个值(比如file.suffix),不能直接“批量”匹配整个目录——那是循环的事。
示例逻辑:
from pathlib import Path
<p>src = Path("downloads")
rules = {
".py": "code",
".jpg": "images",
".pdf": "docs",
".zip": "archives"
}</p><p>for file in src.iterdir():
if file.is<em>file():
match file.suffix.lower():
case ".py" | ".js" | ".ts":
target = src / "code" / file.name
case ".jpg" | ".png" | ".gif":
target = src / "images" / file.name
case ".pdf" | ".docx":
target = src / "docs" / file.name
case </em>:
target = src / "others" / file.name
file.rename(target)
</p>
关键点:
-
match后面必须是可计算的表达式,不能是未定义变量或函数调用(如match file.suffix.lower()合法,match file.rename()不行) - 多个后缀用
|连接,不是逗号 -
case _必须放在最后,否则会拦截所有前面的分支 -
file.suffix包含点(如".py"),别漏掉
遇到文件名含多点时suffix可能不准
pathlib.Path.suffix只返回最后一个点之后的部分,对"archive.tar.gz"返回".gz",不是".tar.gz"。这时要用file.suffixes或正则。
稳妥做法:
- 用
file.suffixes判断是否以[".tar", ".gz"]结尾 - 或用
re.search(r"\.(tar\.gz|tar\.bz2)$", file.name)捕获复合后缀 - 若坚持用
match,可先预处理:ext = "".join(file.suffixes[-2:]) if len(file.suffixes) >= 2 else file.suffix,再match ext
Windows下注意大小写和隐藏文件
Windows文件系统默认不区分大小写,但file.suffix原样返回磁盘上的大小写(如".JPG")。直接match ".jpg"会失败。
建议统一转小写后再匹配:
match file.suffix.lower():
case ".jpg" | ".jpeg":
# ...
另外,iterdir()会包含.DS_Store、Thumbs.db等系统文件,建议加过滤:
if file.is_file() and not file.name.startswith(".")- 或用
glob("*.py")替代iterdir()来限定范围
真正麻烦的是并发修改——如果两个脚本同时重命名同一目录下的文件,rename()可能抛FileExistsError或PermissionError,这种错误match完全不管,得你自己加try/except和重试逻辑。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











