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

Python3.7 tkinter程序写CSV时偶发PermissionError权限错误如何解决

问题描述

我使用Python 3.7开发了一款tkinter应用,功能是从主CSV文件中提取用户预筛选的信息,生成小型报告。当前遇到的问题是:将筛选后的数据写入报告文件时偶发PermissionError,错误回溯信息如下:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\mdiakuly\AppData\Roaming\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "D:/PycharmProjects/report_extractor_hil_sil/report_extractor.py", line 286, in report_generation_prep
    self.report_generation(names_list, relevant_params, specific_value, extracted_file)
  File "D:/PycharmProjects/report_extractor_hil_sil/report_extractor.py", line 344, in report_generation
    processing_data(rd,column)
  File "D:/PycharmProjects/report_extractor_hil_sil/report_extractor.py", line 336, in processing_data
    writing_new_report(gathering_row)
  File "D:/PycharmProjects/report_extractor_hil_sil/report_extractor.py", line 299, in writing_new_report
    with open(extracted_file, 'a+', newline='') as write_in:
PermissionError: [Errno 13] Permission denied: 'C:/Users/myusername/Desktop/reporter/Partial_report_14_10_2021T15-13-12.csv'

该错误的出现无固定规律:有时仅写入1行就触发报错,有时可完整完成全部导出无报错,还有时写入数千行后才触发报错,且写入过程中目标CSV文件始终处于未打开状态。
相关业务代码如下:

def writing_new_report(complete_row):
    with open(extracted_file, 'a+', newline='') as write_in:
        wt = csv.DictWriter(write_in, delimiter=';', fieldnames=relevant_params)
        if self.debug:
            print(complete_row)
        wt.writerow(complete_row)

def processing_data(r_d,column='def'):
    for idx, row in enumerate(r_d): #looping through major csv
        self.progress.update()
        if self.debug:
            print(f'{idx:}',end=' / ')
        gathering_row = {}
        if column != 'def':
            if row[column] not in names_list:
                continue
            else:
                names_list.remove(row[column])
                pass
        else:
            pass

        for param, value in zip(relevant_params,specific_value):
            self.progress.update()
            if self.debug:
                print(f'{row[param]:}',end=' / ')
            gathering_row[param] = row[param]
            if value == '---- All ----':
                pass
            elif value != row[param]:
                if self.debug:
                    print(f'{row[param]:} - Skipped')
                break

            if param == relevant_params[len(relevant_params)-1]:
                if self.debug:
                    print(f'{row[param]:} - Written')
                writing_new_report(gathering_row)

请问是否有人遇到过同类问题?有什么可行的修复方案?


解决方案

这个偶发权限报错是Windows系统下频繁开关同一文件的典型问题:当前逻辑是每写入一行就调用一次open打开文件再自动关闭,Windows系统的文件锁释放存在短暂延迟,杀毒软件、文件索引服务等后台进程也可能在文件关闭后短时间内持有文件锁,再次调用open就会触发权限报错。
修复方案可按优先级选择:

  • 方案1:重构代码,仅打开一次文件完成所有写入(最优)
    不要每行开关一次文件,在处理数据前就初始化文件对象和DictWriter,所有行写入完成后再关闭文件,从根源避免频繁开关文件的问题,同时还能提升写入效率。示例代码参考:
    # 在调用processing_data前先完成文件初始化
    with open(extracted_file, 'w', newline='') as write_in:
        wt = csv.DictWriter(write_in, delimiter=';', fieldnames=relevant_params)
        wt.writeheader() # 如果需要写表头的话加这行
        
        def writing_new_report(complete_row):
            if self.debug:
                print(complete_row)
            wt.writerow(complete_row)
        
        # 调用processing_data处理所有数据
        processing_data(rd, column)
    
  • 方案2:增加写入重试机制
    如果确实需要保留每次写入单独打开文件的逻辑,可以增加重试逻辑,碰到权限错误时等待短时间后重试,最多重试3-5次即可覆盖绝大多数系统锁延迟的场景。示例代码参考:
    import time
    def writing_new_report(complete_row, retry_times=3):
        for i in range(retry_times):
            try:
                with open(extracted_file, 'a+', newline='') as write_in:
                    wt = csv.DictWriter(write_in, delimiter=';', fieldnames=relevant_params)
                    if self.debug:
                        print(complete_row)
                    wt.writerow(complete_row)
                return
            except PermissionError:
                if i == retry_times -1: # 最后一次重试失败再抛出错误
                    raise
                time.sleep(0.05) # 等待50毫秒后重试
    
  • 方案3:排除系统层面干扰(辅助)
    将输出目录加入本地杀毒软件的白名单,关闭输出目录的Windows文件索引功能,减少后台进程占用文件的概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:30:02