Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python closes file after a single write()

I'm using Python Version 2.7.10 with macOS Sierra 10.12.16 and Xcode 8.3.3 In the demo program I want to write 2 lines of text in a file. This should be done in two steps. In the first step the method openNewFile() is called. The file is created with the open command and one line of text is written to the file. The file handle is the return value of the method. In the second step the method closeNewFile(fH) with the file handle fH as input argument is called. A second line of text should be written to the file and the file should be closed. However, this leads to an error message:

 Traceback (most recent call last):
  File "playground.py", line 23, in <module>
    myDemo.createFile()
  File "playground.py", line 20, in createFile
    self.closeNewFile(fH)
  File "playground.py", line 15, in closeNewFile
    fileHandle.writelines("Second line")
ValueError: I/O operation on closed file
Program ended with exit code: 1

It seems to me that handling the file over from one method to another could be the problem.

#!/usr/bin/env python
import os

class demo:
    def openNewFile(self):
        currentPath = os.getcwd()
        myDemoFile = os.path.join(currentPath, "DemoFile.txt")
        with open(myDemoFile, "w") as f:
            f.writelines("First line")
            return f

    def closeNewFile(self, fileHandle):
        fileHandle.writelines("Second line")
        fileHandle.close()

    def createFile(self):
        fH = self.openNewFile()
        self.closeNewFile(fH)

myDemo = demo()
myDemo.createFile()

What are I doing wrong? How can this problem be fixed?

like image 358
Heinz M. Avatar asked Jul 28 '26 12:07

Heinz M.


1 Answers

You're mistaken about what with....as does. This code is the culprit here:

 with open(myDemoFile, "w") as f:
    f.writelines("First line")
    return f

Just before the return, with closes the file, so you end up returning a closed file from the function.

I should add -- opening a file in one function and returning it without closing it (what your actual intention is) is major code smell. That said, the fix to this problem would be to get rid of the with...as context manager:

f = open(myDemoFile, "w") 
f.writelines("First line")
return f

An improvement to this would be to not get rid of your context manager, but to carry out all your I/O within the context manager. Don't have separate functions for opening and writing, and don't segment your I/O operations.

like image 183
cs95 Avatar answered Jul 31 '26 00:07

cs95