I'm writing a manager class that will allow creation of different types of log files (raw, CSV, custom data format), and I'd like to keep the log file open to write lines as they come in. The log file can also be started and stopped by events (button presses, conditions).
I want to know if I can combine the with open('file') as file:
syntax, with an instance variable in a class - so I'm not stuck polling in a loop while the file is open, but instead can write to the file by event.
I know how to use the open and close methods, but everyone says "with" is much more robust, and (more) certain to write the file to disk.
I want to do something like this:
class logfile:
def __init__(self,filename,mode):
with open(filename, mode) as self.f:
return
def write(self, input):
self.f.write(input)
and use it like:
lf = logfile("junk.txt","wt") # yeah, lf has to be global to use like this. Keeping demo simple here.
...then leave method, do other stuff to refresh screen, respond to other events, and later when a data line to log comes in:
lf.write(dataline)
I then expect things to close cleanly, file to get flushed to disk when lf disappears - either implicitly at program close, or explicitly when I set lf to None.
When I try this, the file is (apparently) closed at return from creation of lf. I can inspect lf and see that
lf.f == <_io.TextIOWrapper name='junk.txt' mode='wt' encoding='UTF-8'>
but when I try to use lf.write("text")
, I get:
ValueError: I/O operation on closed file.
Is there a way of using "with" and keeping it in an instance?
Failing that, should I just use open, close and write, and ensure I have try/except/finally in init and close in exit?
The with
syntax is a context manager in Python. So, what it does is, it calls file.close()
method once it is out of context. So, the file is closed already after its return. I think you can write your class this way:
class logfile:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def write(self, text):
with open(self.filename, self.mode) as f:
f.write(text)