在Python中关闭CSV文件

4 投票
2 回答
16608 浏览
提问于 2025-04-18 18:24

这段内容和csv写入器没有关闭文件的问题很相似,虽然我不太确定为什么我的情况会不同。

def LoadCSV:
    with open('test.csv', 'r') as csvfile:
        targetReader = csv.reader(csvfile, delimiter=',')
        for row in targetReader:
            ...

然后最后在这个函数里

csvfile.close()

这段代码打开了test.csv文件,和脚本在同一个方向上。我们希望的行为是,当脚本完成对函数中行的处理后,它会把这个表格重命名为test.[时间戳],以便归档,并且监视这个文件夹,等待新的表格到来。

在代码的后面部分;

os.rename('test.csv', "test." + time.strftime("%x") )

出现了一个错误,提示文件无法重命名,因为还有一个进程在使用它。我该如何在完成后关闭这个文件呢?csvfile.close()并没有抛出异常,而且如果我在交互模式下逐步执行代码,我可以看到csvfile是一个“已关闭的文件对象”。这到底是什么?当然,打开的文件是一个对象,但关闭的文件就不是,那我该如何让我的代码忘记这个文件的存在,以便我可以对这个文件进行输入输出操作呢?

2 个回答

0

当你使用 with 这个块的时候,你不需要手动关闭文件,因为它会在这个块结束后自动释放。如果你想让 Python “忘记” 这个文件句柄,你可以用 del csvfile 来删除它。但是因为你已经在使用 with 了,所以不应该在这个块里面删除这个变量。

你可以试试不使用 with 这个块:

csvfile = open('test.csv','r')
targetReader = csv.reader(csvfile, delimiter=',')
for row in targetReader:
    ....
csvfile.close()
del targetReader
os.rename('test.csv','test.'+time.strftime('%x'))

可能是因为当你使用 with 块的时候,csv 读取器仍然在访问这个文件。

2

这不是为了得分。

你的代码本身就不对,因为你的函数名称写错了。如果这不是故意的,最好修改一下,或者给我们一个类似的代码示例,而不是让我们猜问题出在哪里。

简单说一下你代码中的问题:

  1. def LoadCSV 这个写法是不对的。正确的写法是 def LoadCSV()。下面的截图可以证明这一点。注意没有 () 的地方会显示语法错误的标记。

这里输入图片描述

  1. 解决了第一个问题后,你的下一个问题是使用 csvfile.close()。如果代码写得正确,一旦代码离开 with 的范围,文件会自动关闭。即使重命名的部分在函数里面,也不会有问题。

  2. 最后要提醒你的是,使用格式字符串 %x 会生成像 08/25/14 这样的日期字符串,这取决于地区设置。显然,这样是不对的,因为在Windows中,文件名不能包含 /(试试手动重命名一个文件)。最好明确一点,直接使用 %m%d%y

最后,看看我这边运行的代码。如果你的代码结构不是这样,可能会出现我们无法猜测的其他错误。

这里输入图片描述

运行后的结果如下:

这里输入图片描述

参考代码:

import csv
import os
import time

def LoadCSV():
    with open("test.csv", "r") as csvfile:
        targetReader = csv.reader(csvfile, delimiter=",")
        for row in targetReader:
            print row
    new_name = "test.%s.csv" % time.strftime("%m%d%y")
    print new_name
    os.rename("test.csv", new_name)

LoadCSV()

注意,我这边没有监视我的文件。杀毒软件是开的,显然也没有启用多线程。检查一下你其他的脚本是否同时在监视这个文件的变化。最好是在重命名后,把文件作为参数传给另一个函数,而不是监视文件,这可能是它“正在使用”的原因。另一方面,这个我没有测试,可能更好的是复制文件并给它一个新名字,而不是直接重命名。

希望这些能帮到你。

撰写回答