如何解决csv_writer变量导致代码读取CSV部分无法正常运行的问题?
问题:写入CSV后读取为空,需清空csv_writer才能正常读取?
现象描述
编写代码写入CSV文件存储姓名、邮箱和电话号码,随后读取该文件并将数据存入列表输出。但如果不执行csv_writer = "",读取部分的循环会直接跳过,输出空列表。此时csv_reader显示为<_csv.reader object at 0x0000019A529D7EE0>,而非之前以为的<_csv.Dialect object at 0x000002C86E6921C0>。
根本原因
核心问题出在写入文件时没有真正关闭文件:
- 代码中写文件的最后一行是
csv_file.close,这只是引用了文件对象的close方法,没有调用它(正确写法是csv_file.close())。此时文件的缓冲区数据还没刷新到磁盘,文件处于未关闭状态,后续读取时自然读不到内容。 - 当执行
csv_writer = ""时,原来的csv_writer对象被覆盖,失去引用后被Python垃圾回收机制销毁,而csv.writer对象在销毁时会自动调用关联文件的close()方法,数据才真正写入磁盘,读取时就能拿到内容。但这种依赖垃圾回收的方式完全不可靠,不能作为解决方案。
修复方案
方案1:显式调用close()方法
在写入完成后,给csv_file.close加上括号,真正调用文件关闭方法,确保数据写入磁盘:
# 写入CSV文件 import csv headings = ["Name", "Email", "Phone"] names_list = [["Fred","fred@fred.com","01909-9098645"], ["Sue","sue@sue.com","01986-3937586"], ["John","john@john.com","01892-3983753"], ["Beth","beth@beth.com","230492843"], ["beth","bth@3409ldf","3098430432"], ["Bob","bob@bob.com","2304982304"], ["Joe","joe*0394","230482304"]] csv_file = open("names.csv", "w", newline = "") csv_writer = csv.writer(csv_file, delimiter = ",", quotechar = "|") csv_writer.writerow(headings) for data in names_list: csv_writer.writerow(data) csv_file.close() # 加括号,真正执行关闭操作 # 不需要再设置csv_writer = "" # 读取CSV文件 import csv names_list = [] csv_file = open("names.csv", "r", newline = "") csv_reader = csv.reader(csv_file, delimiter = ",", quotechar = "|") for data in csv_reader: if csv_reader.line_num == 1: headings = [data[0], data[1], data[2]] else: name = [data[0], data[1], data[2]] names_list.append(name) csv_file.close() # 读取完成后同样要关闭文件 print(names_list)
方案2:使用with语句(推荐)
with语句会自动管理文件资源,代码块结束后自动关闭文件,彻底避免手动调用close的失误,是Python操作文件的最佳实践:
# 写入CSV文件 import csv headings = ["Name", "Email", "Phone"] names_list = [["Fred","fred@fred.com","01909-9098645"], ["Sue","sue@sue.com","01986-3937586"], ["John","john@john.com","01892-3983753"], ["Beth","beth@beth.com","230492843"], ["beth","bth@3409ldf","3098430432"], ["Bob","bob@bob.com","2304982304"], ["Joe","joe*0394","230482304"]] # with语句自动处理文件打开/关闭 with open("names.csv", "w", newline = "") as csv_file: csv_writer = csv.writer(csv_file, delimiter = ",", quotechar = "|") csv_writer.writerow(headings) for data in names_list: csv_writer.writerow(data) # 代码块结束后文件自动关闭,数据已写入磁盘 # 读取CSV文件 import csv names_list = [] with open("names.csv", "r", newline = "") as csv_file: csv_reader = csv.reader(csv_file, delimiter = ",", quotechar = "|") for data in csv_reader: if csv_reader.line_num == 1: headings = [data[0], data[1], data[2]] else: name = [data[0], data[1], data[2]] names_list.append(name) print(names_list)
补充说明
- 关于
csv_reader的类型:正常情况下csv.reader()返回的就是<_csv.reader object>,你提到的<_csv.Dialect object>是CSV方言配置对象,两者不是同一类型,之前的混淆是对对象类型的误解。 - 依赖垃圾回收触发文件关闭完全不可靠,不要用
csv_writer = ""这种方式解决问题,必须确保文件被正确关闭。
内容的提问来源于stack exchange,提问作者Alex Parker
相关产品推荐
相关产品推荐

