1

The standard answer to "how can I ensure a file is closed in Python" is to wrap the commands in a "with" statement, so that the destructor is called upon exiting the "with" block.

But what about a case where you can't do that because the file handle needs to remain open across a large swath of code? For example, you open the file handle in an object constructor, saving it to an object property, and then referring to the file handle in many object methods.

It would be possible to move the opening of the file handle to the methods themselves, but basically in that case I'd be opening/closing the file every time a method is called, which is far less efficient.

I have tried placing a "close" command in the object destructor (the "del" method), but this does not work.

Stephen
  • 8,508
  • 12
  • 56
  • 96
  • Why does it not work to close the file in the destructor? Is the object not destroyed when you are done with it? If it fails on errors and stays around, you can wrap it in a `try`-`except`-`finally` block. – JohanL Jul 15 '17 at 07:05
  • I'm terminating the program by killing the kernel (i.e. I hit the big stop button in Spyder). I'm not sure what gets executed in that case, if anything. – Stephen Jul 15 '17 at 07:07
  • try/except/finally probably won't work because again, the "open" command is in the constructor but then the program moves along and starts writing from other methods – Stephen Jul 15 '17 at 07:08
  • Well, if you hit the big red button, I am pretty certain that all files held open by the Python process are closed by the operating system. In any case, the behavior won't be different from using `with` rather than manually do `open`-`close`. To use `try` you have to wrap object creation and all usage of the object in the same `try` block, then it should work. But you may find that inconvenient? – JohanL Jul 15 '17 at 07:12
  • Actually I just determined that the destructor isn't being called. I have to figure out why that is. This isn't promising: https://stackoverflow.com/questions/14628486/why-arent-destructors-guaranteed-to-be-called-on-interpreter-exit – Stephen Jul 15 '17 at 07:13
  • Maybe because I'm running in iPython. (Sorry for the stream-of-consciousness comments, I'm pulling an all-nighter). In any case, simply creating my own cleanup method and calling it explicitly works, just have to avoid the big red button and add explicit exit conditions. – Stephen Jul 15 '17 at 07:16
  • But if your OS is POSIX compliant, all your open files should be closed when the process is killed, as seen in https://unix.stackexchange.com/questions/334396/does-killing-a-process-close-all-files-opened-by-that-process – JohanL Jul 15 '17 at 07:19
  • Well, I'm using Windows 7 – Stephen Jul 15 '17 at 07:27
  • I would imagine the same is true for windows, but I don't know, though. Can you see if the files are kept open somehow? – JohanL Jul 15 '17 at 08:21

1 Answers1

0

A dirty but easy win is to keep record of file names when you open them, and make sure file.close(...) appears at the end. Keep a list or wrapping the open() function (suggest by this post) may do the job.

Post check what files are open in Python suggests several solutions like wrapping the built-in file object, command line method and module psutil, etc, maybe some of them would fit in your situations.

Nriuam
  • 101
  • 9