How to structure custom file handleing class in python?

64 Views Asked by At

Writing my file handling class in python I came across this problem file getting closed before I can use it. Guess I can't use with inside class. What then is the safest way to open/close file to avoid it staying open in case my code crashes before I have chance to close the file?

Clarification: I can go without file handling class, but I wanted to have all file operations handled by my own class rather than be part of code.

Basically class has to

  1. open file and keep open
  2. I run file operations later in code as needed
  3. if my script crashes before I close the file then it somehow magically close/release it as well.
class File:

    def __init__(self, ext_file_path):
        self.file_path = ext_file_path

    class FileLow:
        def __init__(self, path):
            self.filePath = path

        def __enter__(self):
            self.fileHandle = open(self.filePath, 'r+b', )  # specify encoding
            return self.fileHandle

        def __exit__(self, *args):
            self.fileHandle.close()
            print("closed file")

    # class end

    def load(self):
        with self.FileLow(self.file_path) as fileHandle:
            self.myfileHandle = fileHandle

    def read(self):
        self.myfileHandle.seek(0)  # go to beginning of file
        return self.myfileHandle.read()  # read file contents

# class end

file = File("D:\\text.txt")

print("loaded file")
file.load()
print("reading file")
print(file.read())

returns

ValueError: seek of closed file
loaded file
closed file
reading file

I could get rid of class File and keep class FileLow as only class, but i am trying to avoid writing all my further app code inside with block

2

There are 2 best solutions below

1
Hai Vu On

The idea of keeping the file open for the duration of the script/program is dangerous. You are risking losing file content. Yes, you can overload the __del__ magic function to close file, but this function might not be called in some situations. A safe design will open the file, quickly read or write then close it right away.

Furthermore, you are trying to reinvent the wheel. Python already has a library called pathlib which provide easy of use and automatic open/close. Here is an example usage:

import pathlib

my_file = pathlib.Path("my.txt")
my_file.write_text("Hello world")
print(my_file.read_text())

In my opinion, you do not need to implement your own file handler at all.

2
SIGHUP On

You could use a cached_property to handle the file descriptor. In that way the file will only be opened once no matter how many times you call the read() function.

from functools import cached_property

class File:
    def __init__(self, filename):
        self._filename = filename
    @cached_property
    def fd(self):
        return open(self._filename, "rb+")
    def read(self):
        self.fd.seek(0)
        return self.fd.read()
    def __del__(self):
        self.fd.close()

file = File("foo.txt")
print(file.read())
print(file.read()