Jedi Wolf
Jedi Wolf

Reputation: 361

Make and write to file in python makes but doesn't write or close file

I have an interesting issue I'm trying to figure out. I have a large program and in part of that program I'm making a .xml file and writing to it (just using strings no lxml or anything). I took that specific code out into its own program for testing and am running into an issue. The code is

import os
directory = 'FileDirectory'
name = 'Test File.xml'

if not os.path.exists('K:\\JOBS\\' + directory + '\\XML Files\\'):
    os.makedirs('K:\\JOBS\\' + directory + '\\XML Files\\')
xmlJob = open('K:\\JOBS\\' + directory + '\\XML Files\\' + name, 'w')
try:
    xmlJob.write('Test write')
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise
xmlJob.close

The code runs through, doesn't give me any errors, the except doesn't trigger, but while the file is made there is nothing written in it. Also I can not delete the file without closing Python first so the .close doesn't seem to be happening either. But if I put print statements after the .write and the .close they both trigger so the program supposedly hits all the lines. The above text is the entire program so there's nothing else to be messing with it.

Now, when I changed to using with everything works. So the code

import os
directory = 'FileDirectory'
name = 'Test File.xml'

with open('K:\\JOBS\\' + directory + '\\XML Files\\' + name, 'w') as xmlJob:
    xmlJob.write('Test write')

runs fine. So obviously I can use the with instead of the open and .close, but at this point in time I want to figure out why the first option failed. I've used practically the exact same code in other programs to write to log files and such and its worked then. Anyone have any ideas?

Upvotes: 0

Views: 171

Answers (1)

user764357
user764357

Reputation:

By typing xmlJob.close you are refering to the class method close on the xmlJob object, but not calling it.

Observe the following:

>>> f = open("tmp.txt")
>>> f
<open file 'tmp.py', mode 'r' at 0x7f906e8c5ae0>
>>> f.close
<built-in method close of file object at 0x7f906e8c5ae0>
>>> f
<open file 'tmp.py', mode 'r' at 0x7f906e8c5ae0>
>>> f.close()
>>> f
<closed file 'tmp.py', mode 'r' at 0x7f906e8c5ae0>

Calling f.close merely prints a representation of that method, and does not call it.

The reason your second block of code works is because the with open(x) as y construct has alot of syntactic sugar behind the scenes. Along with exception handling, it also handles the closing of objects cleanly. Which means you don't need to manually close the file as its closed once the end of the with block is reached.

Upvotes: 3

Related Questions