简体   繁体   中英

Can I use Python 3 'with open(filename, mode) as file:' and keep it in an object to send it events?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM