Python os.rename批量重命名 跳过文件夹及文件还原问题
问题核心诉求
- 遍历
C:\picturesandvideos及其子目录执行重命名时,实现仅修改文件名、不改动文件夹名称的效果,确认是否需要使用files.append方法跳过文件夹 - 通过单个脚本批量移除文件名上添加的
L0cked!_前缀,将所有文件恢复为原始名称,同时理清实现逻辑的底层原理
你原有存在逻辑问题的代码如下:
import os current_dir = __file__[ : __file__.rfind(os.sep)+1] my_working_file = __file__.replace(current_dir, '') folder = 'C:\\picturesandvideos' for root,dirs,files in os.walk(folder): for file in files: if file in [my_working_file]: continue all_folders = os.path.join(root + '\\') source = all_folders + file print(all_folders) destination = all_folders + f'L0cked!_{file}' locked_tag = 'L0cked!_' remove_locked = all_folders + f'{file}' if locked_tag in locked_filename: #to make everything normal. old_name = (locked_filename.replace(locked_tag,(''))) os.rename(source, old_name) # Renaming the file os.rename(source, destination) #this will change the name with L0cked!_
逻辑原理解释
1. 关于是否需要跳过文件夹的说明
完全不需要用files.append实现跳过文件夹的效果,原因如下:
os.walk()本身在遍历目录时就已经做了类型拆分:每次迭代返回的三个值中,root是当前遍历到的文件夹绝对路径,dirs是当前路径下所有子文件夹的名称列表,files是当前路径下所有文件的名称列表。你直接遍历files列表时,拿到的元素天然全是文件,不会包含任何文件夹,默认就不会修改文件夹名称,不需要额外加跳过逻辑。- 补充:
files.append的作用是向文件列表里追加元素,和“跳过”逻辑完全无关,属于方法误用。只有当你需要跳过某些指定子文件夹、不进入这些子目录遍历时,才需要原地修改dirs列表,删除不需要遍历的文件夹名。
2. 批量添加/移除前缀的正确逻辑
你原有代码的核心问题有三个:
- 使用了未定义的变量
locked_filename,运行会直接报错 - 加前缀和移除前缀的逻辑写在同一个循环分支里,会出现刚给文件加完前缀又立刻改回原名、或者给已经带前缀的文件重复加前缀的问题
- 手动拼接路径时硬编码
\\分隔符,容易出现路径格式错误,跨场景兼容性差
移除前缀的核心判断逻辑:
遍历到每个文件时,优先判断文件名是否以L0cked!_开头(不要用in做包含判断,否则如果文件名中间刚好出现这串字符,会被误替换),确认匹配后切掉开头对应长度的前缀字符,再执行重命名即可。建议给脚本加模式开关,切换加锁/解锁状态时不需要重复修改代码。
修正后可直接运行的代码
import os # 基础配置 WORK_FOLDER = r'C:\picturesandvideos' LOCK_TAG = 'L0cked!_' # 模式开关:True=给所有未加前缀的文件添加L0cked!_前缀,False=移除所有文件的L0cked!_前缀恢复原名 LOCK_MODE = False # 获取当前脚本自身文件名,避免重命名操作误改脚本本身 current_script_name = os.path.basename(os.path.abspath(__file__)) for root, dirs, files in os.walk(WORK_FOLDER): for file_name in files: # 跳过脚本自身 if file_name == current_script_name: continue source_path = os.path.join(root, file_name) if LOCK_MODE: # 加前缀逻辑:已经带前缀的文件跳过,避免重复添加 if not file_name.startswith(LOCK_TAG): new_name = f"{LOCK_TAG}{file_name}" target_path = os.path.join(root, new_name) os.rename(source_path, target_path) print(f"已加锁:{source_path} -> {target_path}") else: # 恢复原名逻辑:只有带指定前缀的文件才执行操作 if file_name.startswith(LOCK_TAG): # 移除开头的前缀,Python3.9以下版本可替换为 original_name = file_name[len(LOCK_TAG):] original_name = file_name.removeprefix(LOCK_TAG) target_path = os.path.join(root, original_name) os.rename(source_path, target_path) print(f"已恢复:{source_path} -> {target_path}")
关键注意事项
- Windows路径前加
r标记为原始字符串,不需要手动写双反斜杠转义,减少路径书写错误 - 必须用
startswith()判断前缀,不要用in做模糊匹配,避免误改文件名 - 重命名前先做状态判断,避免重复加前缀、对无对应前缀的文件执行移除操作触发报错
- 全程使用
os.path.join()拼接路径,不要手动硬编码路径分隔符,自动适配不同系统的路径格式
内容的提问来源于stack exchange,提问作者slste
相关产品推荐
相关产品推荐

