You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用多字符串作为键批量重命名文件并简化重复代码?

文件重命名程序重复代码优化方案

问题描述

我正在开发一款用于清理文件名的文件重命名程序,目前功能可正常运行,但希望优化清理模块的重复代码。期望实现如下逻辑:遍历目录文件时,同时判断多个字符串(如keypar、keyperiod、keydblspc)是否存在于文件名中,执行替换重命名操作,而非多次重复编写遍历与重命名循环。当前代码存在大量重复的遍历和重命名逻辑,曾尝试使用列表实现但遇到问题,现寻求解决方案。

原代码(未优化版本)

import os
from tkinter import Tk
from tkinter.filedialog import askdirectory

print("第一步,请选择包含待重命名文件的文件夹。")
print("选择完成后,可输入最多3个要从文件名中移除的关键词,不需要的输入留空即可。\n")

dirName = askdirectory()  # 弹出对话框并返回路径
print(dirName)

keyword1 = input("请输入第一个要移除的关键词:")  # 第一个关键词
keyword2 = input("请输入第二个要移除的关键词:")  # 可留空
keyword3 = input("请输入第三个要移除的关键词:")  # 可留空

# 预设清理关键词
keypar = "()"  # 清理括号,避免分别处理720和(720)
keyperiod = "."
keyjpg = "jpg"
keymov = " mov"
keymkv = " mkv"
keygif = " gif"
keymp4 = " mp4"
keymp3 = " mp3"
keydblspc = "  "

# 检测包含用户输入关键词的文件
for fname in os.listdir(dirName):
    if keyword1 in fname or keyword2 in fname or keyword3 in fname:
        print(f"{fname} 包含指定关键词")

# 用户输入关键词替换
for filename in os.listdir(dirName):
    if keyword1 in filename:    
        filepath = os.path.join(dirName, filename)
        newfilepath = os.path.join(dirName, filename.replace(keyword1, ""))
        os.rename(filepath, newfilepath)

for filename in os.listdir(dirName):
    if keyword2 in filename:    
        filepath = os.path.join(dirName, filename)
        newfilepath = os.path.join(dirName, filename.replace(keyword2, ""))
        os.rename(filepath, newfilepath)

for filename in os.listdir(dirName):
    if keyword3 in filename:    
        filepath = os.path.join(dirName, filename)
        newfilepath = os.path.join(dirName, filename.replace(keyword3, ""))
        os.rename(filepath, newfilepath)

# 预设关键词清理
for filename in os.listdir(dirName):
    if keypar in filename:    
        filepath = os.path.join(dirName, filename)
        newfilepath = os.path.join(dirName, filename.replace(keypar, ""))
        os.rename(filepath, newfilepath)

for filename in os.listdir(dirName):
    if keyperiod in filename:    
        filepath = os.path.join(dirName, filename)
        newfilepath = os.path.join(dirName, filename.replace(keyperiod, ""))
        os.rename(filepath, newfilepath)

# 输出重命名结果
for fname in os.listdir(dirName):
   print(f"{fname} 已完成重命名")

优化方案

核心思路是:只遍历一次目录,对每个文件名依次应用所有替换规则,避免多次重复遍历目录和重复编写重命名逻辑。

具体步骤:

  1. 把所有需要替换的关键词(用户输入+预设)整理成一个列表,自动过滤空字符串(避免处理用户留空的输入)。
  2. 遍历目录中的每个文件,基于原文件名生成经过所有替换后的新文件名。
  3. 对比新旧文件名,若有变化则执行重命名操作。

优化后代码

import os
from tkinter import Tk
from tkinter.filedialog import askdirectory

print("第一步,请选择包含待重命名文件的文件夹。")
print("选择完成后,可输入最多3个要从文件名中移除的关键词,不需要的输入留空即可。\n")

dirName = askdirectory()
print(dirName)

# 获取用户输入的关键词
user_keywords = [
    input("请输入第一个要移除的关键词:"),
    input("请输入第二个要移除的关键词:"),
    input("请输入第三个要移除的关键词:")
]

# 预设清理关键词
preset_keywords = [
    "()",  # 清理括号
    ".",
    "jpg",
    " mov",
    " mkv",
    " gif",
    " mp4",
    " mp3",
    "  "  # 清理双空格
]

# 合并所有关键词,过滤空字符串
all_replacements = [kw for kw in user_keywords + preset_keywords if kw.strip()]

# 遍历目录,一次性完成所有替换
for filename in os.listdir(dirName):
    # 跳过目录(只处理文件)
    file_path = os.path.join(dirName, filename)
    if os.path.isdir(file_path):
        continue
    
    new_filename = filename
    # 依次应用所有替换规则
    for kw in all_replacements:
        new_filename = new_filename.replace(kw, "")
    
    # 若文件名有变化,则执行重命名
    if new_filename != filename:
        new_path = os.path.join(dirName, new_filename)
        # 避免重名冲突
        if not os.path.exists(new_path):
            os.rename(file_path, new_path)
            print(f"已重命名:{filename} -> {new_filename}")
        else:
            print(f"跳过:{new_filename} 已存在,无法重命名原文件 {filename}")

print("\n所有文件处理完成")

优化点说明:

  • 减少遍历次数:从原代码的多次遍历目录,改为只遍历一次,提升效率。
  • 消除重复代码:把所有替换逻辑统一到一个循环中,避免重复编写重命名代码块。
  • 自动过滤空值:用户留空的输入会被自动排除,无需额外判断。
  • 增加鲁棒性:添加了跳过目录、避免重名冲突的逻辑,减少出错概率。
  • 扩展性强:后续新增关键词只需添加到preset_keywords列表中即可,无需修改遍历逻辑。

内容的提问来源于stack exchange,提问作者JWatson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:45:37