Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closing a CSV file in Python

Tags:

python

csv

This is similar or identical to csv writer not closing file but I'm not 100% sure why my behaviour is different.

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

then finally in the function

csvfile.close()

This opens the test.csv file in the same direction as the script. Desired behaviour is for when the script has done what it's doing to the rows in the function, it renames the sheet to test.[timestamp] to archive it and watches the directory for a new sheet to arrive.

Later down the code;

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

Gives an error that the file can't be renamed because a process is still using it. How do I close this file once I'm done? csvfile.close() doesn't raise an exception, and if I step through my code in interactive mode I can see that csvfile is a "closed file object." What even is that? Surely an open file is an object but a closed one isn't, how do I make my code forget this even exists so I can then do IO on the file?

like image 833
Elomis Avatar asked May 17 '26 06:05

Elomis


1 Answers

NOT FOR POINTS.

Code is not valid anyway, since your function name is wrong. If that was not intentional, better edit it or to produce a pseudo-replica of your code, rather than have us guess what the issue is.

To iterate, the issues with your code:

  1. def LoadCSV is not valid. def LoadCSV() is. Proof in following screenshot. Notice how the lack of () is showing syntax error markers.

enter image description here

  1. Fixing (1) above, your next problem is using csvfile.close(). If the code is properly written, once the code is out of the scope of with, the file is closed automatically. Even if the renaming part of the code is inside the function, it shouldn't pose any problems.

  2. Final word of warning -- using the format string %x will produce date-strings like 08/25/14, depending on locale. Obviously, this is erroneous, as a / is invalid in filenames in Windows (try renaming a file manually with this). Better to be very explicit and just use %m%d%y instead.

Finally, see the running code on my end. If your code is not structured like this, then other errors we cannot guess might arise.

enter image description here

Result as follows after running:

enter image description here

Code for reference:

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()

Note that on my end, there is nothing that watches my file. Antivirus is on, and no multithreading obviously is enabled. Check if one of your other scripts concurrently watches this file for changes. It's better if instead of watching the file, the file is sent as an argument post-renaming to this other function instead, as this might be the reason why it's "being used". On the one hand, and this is untested on my side, possibly better to copy the file with a new name rather than rename it.

Hope this helps.

like image 187
NullDev Avatar answered May 18 '26 18:05

NullDev