Python 按序号批量重命名文件:照片报表编号实战
用 Python 给一批文件按序号批量重命名,如 001.jpg、002.jpg,支持起始号、位数、步长和 dry-run 预览,整理照片、扫描件、合同必备。
场景痛点
拍了一百张照片、扫描了一堆合同,导出来名字全是 IMG_0012.jpg、扫描件(3).pdf,顺序和内容对不上。想按拍摄或导入顺序统一编成 项目A_001.jpg、项目A_002.jpg,手动拖改既慢又容易漏。用 Python 按排序后的文件列表依次编号,一次跑完还能保留原扩展名。
用到的库
纯标准库,无需 pip 安装:
# os、os.path 为标准库
完整代码
import os
# ========== 配置区 ==========
TARGET_DIR = "./照片" # 要编号的文件夹
PREFIX = "团建_" # 文件名前缀,不需要就留空 ""
START = 1 # 起始序号
WIDTH = 3 # 序号位数,3 -> 001、002...
STEP = 1 # 步长
DRY_RUN = True # True=预览,False=真正改名
# ============================
def main():
if not os.path.isdir(TARGET_DIR):
print(f"目录不存在:{TARGET_DIR}")
return
# 取出所有文件,并按文件名排序,保证编号顺序稳定
files = [
name for name in os.listdir(TARGET_DIR)
if os.path.isfile(os.path.join(TARGET_DIR, name))
]
files.sort() # 想按修改时间排可改用 os.path.getmtime 排序
index = START
count = 0
for name in files:
stem, ext = os.path.splitext(name)
# 拼新名字:前缀 + 序号(补零) + 原扩展名
new_name = f"{PREFIX}{str(index).zfill(WIDTH)}{ext}"
index += STEP
old_path = os.path.join(TARGET_DIR, name)
new_path = os.path.join(TARGET_DIR, new_name)
if os.path.exists(new_path) and new_path != old_path:
print(f"[跳过] 目标已存在:{new_name}")
continue
print(f"[{'预览' if DRY_RUN else '执行'}] {name} -> {new_name}")
if not DRY_RUN:
os.rename(old_path, new_path)
count += 1
print(f"\n共 {count} 个文件(DRY_RUN={DRY_RUN})")
if __name__ == "__main__":
main()
代码讲解
- files.sort():先把文件名排好序再编号,这样每次运行结果一致,不会因为
os.listdir返回顺序不稳定而编号乱跳。想按时间排序就把这行换成按os.path.getmtime取值排序。 - str(index).zfill(WIDTH):把序号补零到固定位数。
WIDTH=3时1变成001,文件在资源管理器里就能正确按顺序排列,不会出现10.jpg排在2.jpg前面的问题。 - 保留扩展名:
os.path.splitext把主名和扩展名拆开,新名只换主名,扩展名原样保留,图片还是图片、PDF 还是 PDF。 - 前缀 PREFIX:可以加项目名、类别名,让编号自带语义。不需要就设成空字符串。
运行结果
终端逐条打印 旧名 -> 团建_001.jpg 这样的对照。预览确认顺序和编号都对,把 DRY_RUN 改成 False 再跑一次,文件就按 团建_001、团建_002... 排列好了。
注意事项
- 两次改名要小心:如果文件夹里已经是
团建_001这种名字,再跑一次会把团建_001又编成团建_001,看起来没变但中间状态可能冲突。正式跑前先预览。 - 别直接对已有编号二次编号:避免序号错位。
- 排序方式决定编号顺序:按文件名排和按拍摄时间排结果完全不同,先想清楚要哪种顺序。
- 大文件别在原盘直接改:建议先复制一份到测试目录验证。
- 跨卷改名:
os.rename不能跨磁盘,目标要和源在同一目录。

更新时间:2026-09-14 21:26:09