How to close all python-opened file identifiers?

B

BAnderton

Greetings from beautiful Tucson, Arizona.

Question: Is there a way in Python to determine what all file
identifiers have been opened by Python, and to close them all?

Why I ask: I learned Python after cutting my programming teeth on
Matlab, where you get a list of all open file identifiers (that is,
those opened from a particular Matlab session) with "fopen('all')" and
close them with "fclose('all')". In my 4 years of experience with
Python, I haven't yet come across an equivalent means of doing this in
Python. I understand that this problem can be prevented by making
sure a "fid.close()" exists for every "open"; I need this however for
a file-permissions troubleshooting problem.

Extra info on this specific problem: In my program, python (through
subprocess) launched a text editor on a text file, and I can't seem to
save the text file through that editor (I get a "this document is in
use by another application and cannot be accessed" error from the
editor [wordpad on winXp]). The text file in question is modified by
my program prior to its loading into the launched editor. Although I
can't find unmatched "open" and "fid.close()" statements, I'd like to
implement a check for open file identifiers before launching the
editor.

Thanks very much in advance for your time and any help you can provide.
 
T

Tim Roberts

BAnderton said:
Question: Is there a way in Python to determine what all file
identifiers have been opened by Python, and to close them all?

No. You are expected to be able to track this yourself. Python doesn't
open any files that you didn't request.

Extra info on this specific problem: In my program, python (through
subprocess) launched a text editor on a text file, and I can't seem to
save the text file through that editor (I get a "this document is in
use by another application and cannot be accessed" error from the
editor [wordpad on winXp]). The text file in question is modified by
my program prior to its loading into the launched editor. Although I
can't find unmatched "open" and "fid.close()" statements, I'd like to
implement a check for open file identifiers before launching the
editor.

If you want to post some code, perhaps we can find something.
 
M

Michele Simionato

can't find unmatched "open" and "fid.close()" statements, I'd like to
implement a check for open file identifiers before launching the
editor.

So you need a debug tool to track down the opened files.
How about that:

# assume Python 2.5
from __future__ import with_statement

import __builtin__

orig_file = __builtin__.file # you could do the same for open

class ChattyFile(file):
opened = []
def __init__(self, *args, **kw):
super(ChattyFile, self).__init__(*args, **kw)
self.opened.append(self)
print 'opened %s' % self
def close(self):
super(ChattyFile, self).close()
self.opened.remove(self)
print 'closed %s' % self

class ContextManager(object):
def __init__(self):
self.opened = ChattyFile.opened
def __enter__(self):
__builtin__.file = ChattyFile
def __exit__(self, *exc_info):
__builtin__.file = orig_file

chattyfile = ContextManager()

with chattyfile:
f = file('x.txt', 'w')
f.write('hello')
f.close()
file('x.txt')

print chattyfile.opened

gives:

$ python chattyfile.py
opened <open file 'x.txt', mode 'w' at 0x19df0>
closed <closed file 'x.txt', mode 'w' at 0x19df0>
opened <open file 'x.txt', mode 'r' at 0x19e48>
[<open file 'x.txt', mode 'r' at 0x19e48>]

Warning: I did not test this more than you see.
Notice also that overriding the builtins is fine
for debugging purposes (it is perhaps the only good
use case for this feature, together with testing, for mock objects).
You are expected to use it as follows:

from chattyfile import chattyfile
from mylibrary import main

with chattyfile:
main()

and all calls to 'file' will be tracked down.
Since 'open' is basically an alias for 'file'
(they were exactly the same in Python 2.4)
you could also track 'open' in the same way.
If you are using Python 2.4 you can use the same
trick, but in a less clean way, using a try ..finally
instead of the context manager.

Michele Simionato
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,235
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top