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

如何用Python导入CSV文件并避免‘已关闭文件上的I/O操作’错误

问题分析与解决方案

核心错误原因

你遇到的I/O operation on closed file.错误,是因为with语句块执行结束后,会自动关闭关联的文件对象insurance_data,此时在块外调用函数访问该文件对象,自然会触发已关闭文件的I/O操作错误。此外,你的函数代码还存在语法、数据类型处理的问题,需要一并修正。


修正方案一:在with块内完成统计

将函数定义和调用都放在with块内部,确保文件处于打开状态时完成数据遍历:

import csv

with open("insurance.csv", newline="") as insurance_data:
    insurance_reader = csv.DictReader(insurance_data)
    
    def bmi_categories(reader):
        obese_counter = 0
        overweight_counter = 0
        # 遍历每一条记录
        for item in reader:
            # 将CSV中读取的字符串类型BMI转为数值型
            bmi = float(item["BMI"])
            if 25 < bmi <= 30:
                overweight_counter += 1
            elif bmi > 30:
                obese_counter += 1
        # 返回统计结果
        return {"超重人数": overweight_counter, "肥胖人数": obese_counter}
    
    # 调用函数并打印结果
    stat_result = bmi_categories(insurance_reader)
    print(f"统计结果:{stat_result}")

修正方案二:先缓存数据再统计

如果需要在with块外处理数据,可以先把所有记录读取到列表中,文件关闭后依然能使用缓存的数据:

import csv

# 先读取所有数据到列表,缓存下来
insurance_records = []
with open("insurance.csv", newline="") as insurance_data:
    insurance_reader = csv.DictReader(insurance_data)
    insurance_records = list(insurance_reader)

def bmi_categories(records):
    obese_counter = 0
    overweight_counter = 0
    for item in records:
        bmi = float(item["BMI"])
        if 25 < bmi <= 30:
            overweight_counter += 1
        elif bmi > 30:
            obese_counter += 1
    return {"超重人数": overweight_counter, "肥胖人数": obese_counter}

# 调用函数并输出结果
stat_result = bmi_categories(insurance_records)
print(f"统计结果:{stat_result}")

关键修正点说明

  1. 文件生命周期问题:with块的设计就是自动管理文件开闭,所以要么在块内完成所有文件操作,要么提前将数据缓存到内存对象(比如列表)中。
  2. 语法与数据类型:
    • 原代码for item[BMI] in file是错误语法,应改为遍历每条记录item,再通过字符串键item["BMI"]取值。
    • CSV读取的所有字段都是字符串类型,必须用float()转换为数值后才能进行大小比较。
  3. 结果返回:让函数返回统计结果字典,方便后续查看或进一步处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 02:20:28