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

使用Python的shutil.move重命名文件时触发FileNotFoundError问题

文件名补全脚本的FileNotFoundError问题解决

我正在学习《Automate the Boring Stuff》第10章,其中一项任务要求补全缺失序号的文件名(例如将capitalsquiz1、capitalsquiz3这类不连续的文件名重命名为连续序号)。编写代码后,注释shutil.move仅用print测试时,程序逻辑符合预期,但启用shutil.move后触发了FileNotFoundError。

我的代码

def fill_gap(folder):
    print(f'in {folder}')
    #create regex to find numbered filenames
    num = re.compile(r'^(.*?)((\d)?(\d)?(\d))')
    
    order =[]
    out = []
    #go through all the files in the folder
    for oldfile in os.listdir(folder):
        
            
        mo = num.search(oldfile)
            
        if mo == None:
                continue
            
        order.append(mo.group(2))
        
    order.sort(key = int)
       
    for i in range(len(order)):

        order[i] = mo.group(1) + order[i]
        out.append(mo.group(1)+str(i+1))
        
    print(order)
    print(out)
    
    for i in range(len(order)):
        
        
        main = os.path.abspath(folder)
        old = os.path.join(main,order[i])
        
        order[i] = out[i]

        new = os.path.join(main, order[i])
        
        print(os.path.basename(old))
        print(os.path.basename(new))
        print (f'renaming "{old}" to "{new}"...')
        #shutil.move(old, new) 
                
                
            
fill_gap(r'C:\\Users\Andrei\pyject\rand_quiz')

报错信息

Traceback (most recent call last):
  File "C:\Program Files\Python311\Lib\shutil.py", line 825, in move
    os.rename(src, real_dst)
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'C:\\Users\\Andrei\\pyject\\rand_quiz\\capitalsquiz1' -> 'C:\\Users\\Andrei\\pyject\\rand_quiz\\capitalsquiz1'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Andrei\pyject\fill_gap_in_name.py", line 53, in <module>
    fill_gap(r'C:\\Users\Andrei\pyject\rand_quiz')
  File "C:\Users\Andrei\pyject\fill_gap_in_name.py", line 48, in fill_gap
    shutil.move(old, new)
  File "C:\Program Files\Python311\Lib\shutil.py", line 845, in move
    copy_function(src, real_dst)
  File "C:\Program Files\Python311\Lib\shutil.py", line 436, in copy2
    copyfile(src, dst, follow_symlinks=follow_symlinks)
  File "C:\Program Files\Python311\Lib\shutil.py", line 256, in copyfile
    with open(src, 'rb') as fsrc:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Andrei\\pyject\\rand_quiz\\capitalsquiz1'

问题根源

  1. 前缀信息丢失:第一个循环只把序号存入order列表,后续拼接前缀时用的是最后一次循环的mo.group(1),如果文件夹内文件前缀不一致,会生成错误的旧文件名。
  2. 修改原始文件名列表:重命名循环中修改了order[i]的值,导致后续循环的旧路径指向已经被修改的名称,自然找不到文件。
  3. 正则未匹配扩展名:你的正则没考虑文件后缀(比如.txt),生成的路径缺少扩展名,系统找不到对应文件。

修复后的代码

import os
import re
import shutil

def fill_gap(folder):
    print(f'in {folder}')
    # 匹配带序号的文件名(包含扩展名)
    num_pattern = re.compile(r'^(.*?)(\d+)(\..*)?$')
    
    # 存储完整文件信息:(前缀, 序号, 扩展名, 原始文件名)
    file_info_list = []
    
    # 遍历文件夹内所有文件
    for oldfile in os.listdir(folder):
        mo = num_pattern.search(oldfile)
        if not mo:
            continue
        prefix = mo.group(1)
        num = int(mo.group(2))
        ext = mo.group(3) or ''  # 处理无扩展名的情况
        file_info_list.append( (prefix, num, ext, oldfile) )
    
    # 按序号排序
    file_info_list.sort(key=lambda x: x[1])
    
    # 生成新文件名并执行重命名
    main_path = os.path.abspath(folder)
    for idx, (prefix, _, ext, old_filename) in enumerate(file_info_list, start=1):
        old_path = os.path.join(main_path, old_filename)
        new_filename = f'{prefix}{idx}{ext}'
        new_path = os.path.join(main_path, new_filename)
        
        print(f'renaming "{old_path}" to "{new_path}"...')
        shutil.move(old_path, new_path)
            
fill_gap(r'C:\Users\Andrei\pyject\rand_quiz')

修复说明

  • 正则优化:新增扩展名匹配逻辑,确保文件名完整。
  • 存储完整信息:保存每个文件的前缀、序号、扩展名和原始文件名,避免信息丢失。
  • 不修改原始列表:循环时直接使用存储的原始文件名,避免路径指向错误。
  • 清晰排序逻辑:用lambda表达式直接按序号排序,可读性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:22:01