Python脚本报WinError32:文件被其他进程占用问题求助
问题描述
我在Spyder中编写了一个供同事和自己使用的小型脚本,用于更新简单的Excel文件。自己运行代码时无报错,但同事运行相同代码时,出现错误提示:进程无法访问文件,因为该文件正被其他进程占用。已尝试在同事运行时关闭自己的程序、将文档重命名后重新运行,但错误仍未解决。
文件路径(已移除公司信息前缀)
#Files swx_f = 'Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\SWX' + dayval + '.xlsx' caris_f = 'Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\CARIS' + dayval + '.xlsx' cspcaris_f = 'Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\CSPvsCARIS' + dayval + '.xlsx'
错误代码
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\saed\\OneDrive\\Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\SWX202408.xlsx' -> 'C:\\Users\\saed\\Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\File Archive\\SWX202408.xlsx' During handling of the above exception, another exception occurred: Traceback (most recent call last): File ~\AppData\Local\anaconda3\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals) File c:\users\saed\.spyder-py3\monthly closure.py:107 shutil.move(swx_f, dest_new) File ~\AppData\Local\anaconda3\Lib\site-packages\shutil.py:868 in move os.unlink(src) PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\saed\\Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\SWX202408.xlsx'
完整代码
###Headers length = 0 header1 = ['AWB Number'] header2 = ['Departure Date', 'Match Status', 'Flight Number', 'Net Revenue Prorated', 'Source'] swxhead = ['AWB Number', 'Origin', 'Destination', 'SWX Net Amount'] ###Lists/Dicts swx_list = [] caris_dict = {} cspcaris_dict = {} final_dict = {} ###Record Counts swxcount = 0 cariscount = 0 cspcariscount = 0 #combinedcount = 0 ###Build SWX List workbook1 = xl.load_workbook(filename=swx_f) wb1 = workbook1.active for line in wb1.iter_rows(values_only=True): if line[2] is not None: if '724-' in line[2]: swxamt = float(line[10]) amtround = np.around(swxamt, decimals=2) swx_list.append([line[2].strip(), line[4].strip(), line[5].strip(), amtround]) swxcount +=1 else: pass else: pass workbook1.close() shutil.move(swx_f, dest_new) ###Build CARIS List workbook2 = xl.load_workbook(filename=caris_f) wb2 = workbook2.active for row in wb2.iter_rows(values_only=True): if row[3] is not None: if '724-' in row[3].strip(): awb = row[3].strip() depdate = row[4] flt = row[5] netrev = row[6] if awb in caris_dict.keys(): caris_dict[awb] += [depdate, flt, netrev, 'CARIS'] cariscount +=1 else: caris_dict[awb] = [depdate, flt, netrev, 'CARIS'] cariscount +=1 else: pass else: pass workbook2.close() shutil.move(caris_f, dest_new) ###Build CSP vs CARIS List workbook3 = xl.load_workbook(filename=cspcaris_f) wb3 = workbook3.active for r in wb3.iter_rows(values_only=True): if r[1] is not None: if '724' in str(r[1]): awb2 = str(r[1]) depdate2 = r[4].strftime('%d/%m/%Y') flt2 = r[3] netrev2 = r[6] if awb2 in cspcaris_dict.keys(): cspcaris_dict[awb2] += [depdate2, flt2, netrev2, 'CSPCARIS'] cspcariscount +=1 else: cspcaris_dict[awb2] = [depdate2, flt2, netrev2, 'CSPCARIS'] cspcariscount +=1 else: pass else: pass workbook3.close() shutil.move(cspcaris_f, dest_new) ###Build Combined CARIS and CSP vs CARIS Dict for k in caris_dict.keys(): if k in cspcaris_dict.keys(): final_dict[k] = ['Matched'] + caris_dict[k] + cspcaris_dict[k] cspcaris_dict[k] += ['Matched'] else: final_dict[k] = ['No Match'] + caris_dict[k] for j in cspcaris_dict.keys(): if cspcaris_dict[j][-1] == 'Matched': pass elif j in caris_dict.keys(): final_dict[j] = ['Matched'] + caris_dict[j] + cspcaris_dict[j] else: final_dict[j] = ['No Match'] + cspcaris_dict[j] for l in final_dict.keys(): if len(final_dict[l]) > length: length = len(final_dict[l]) else: pass ###Write Final File### ###Create report counts for error checking indtotal = swxcount + cariscount + cspcariscount ####Headers multiplier = int(length / 5) variablehead = header2 * multiplier final_head = header1 + variablehead ###Create workbook and name sheets wb = xl.Workbook() ws1 = wb.create_sheet('CARIS CSP', 0) ws2 = wb.create_sheet('SWX', 1) ws3 = wb.create_sheet('Record Counts', 2) ws3.append(['Record Counts - Individual Reports', 'SWX Records:', swxcount, 'CARIS Records:', cariscount, 'CSP vs CARIS Records:', cspcariscount, 'Total:', indtotal]) #ws2.append(['Record Counts - This Report', '', '', 'Combined Records:', combinedcount, 'Unique Records:', uniquecount, 'Total:', reporttotal]) ws2.append(swxhead) for t in swx_list: ws2.append(t) ws1.append(final_head) for w in final_dict.keys(): newlist = [w] + final_dict[w] ws1.append(newlist) outputfile = r'C:\\Users\\' + user_code + '\\Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\Completed Reports\\SWXCARISCSP Records Report ' + dayval + 'TESTTEST.xlsx' wb.save(outputfile) wb.close() messagebox.showinfo("Success!", "Report Completed") master_with_quotes = '"' + outputfile + '"' os.system('start "EXCEL.exe" {}'.format(master_with_quotes))
问题根源与解决办法
1. OneDrive同步锁定
同事的文件路径包含OneDrive,OneDrive的实时同步机制会在文件被读取/修改时自动锁定文件,导致shutil.move无法操作。
- 临时解决:让同事暂停OneDrive同步,运行完脚本后再恢复;
- 永久优化:修改脚本逻辑,先将文件从OneDrive复制到本地非同步目录,处理完成后再归档到目标位置。
2. Excel进程残留或隐性占用
即使手动关闭了Excel,系统后台可能仍有EXCEL.EXE进程残留,或者文件被杀毒软件、预览工具等后台程序锁定。
- 让同事打开任务管理器,结束所有
EXCEL.EXE进程; - 关闭文件资源管理器的预览功能,避免系统自动锁定文件;
- 在脚本中添加延迟,确保
workbook.close()完全释放文件后再执行shutil.move,例如在close()后添加time.sleep(2)。
3. 代码优化:确保文件句柄完全释放
虽然代码中调用了workbook.close(),但openpyxl偶尔会因缓存或上下文问题未彻底释放文件,改用with上下文管理器可以更稳妥地管理文件资源:
###Build SWX List with xl.load_workbook(filename=swx_f) as workbook1: wb1 = workbook1.active for line in wb1.iter_rows(values_only=True): if line[2] is not None: if '724-' in line[2]: swxamt = float(line[10]) amtround = np.around(swxamt, decimals=2) swx_list.append([line[2].strip(), line[4].strip(), line[5].strip(), amtround]) swxcount +=1 # with块结束后自动关闭workbook,无需手动调用close() shutil.move(swx_f, dest_new)
按此方式修改CARIS和CSPvsCARIS的读取代码,确保文件句柄被正确释放。
4. 路径格式规范
Windows系统下建议使用原始字符串(rf"")定义路径,避免转义字符导致的路径识别错误:
swx_f = rf'Internal Team Library\Team\CS\Darian\CARISCSPSWX_Report\SWX{dayval}.xlsx' caris_f = rf'Internal Team Library\Team\CS\Darian\CARISCSPSWX_Report\CARIS{dayval}.xlsx' cspcaris_f = rf'Internal Team Library\Team\CS\Darian\CARISCSPSWX_Report\CSPvsCARIS{dayval}.xlsx'
内容的提问来源于stack exchange,提问作者dare1331
相关产品推荐
相关产品推荐

