1

I have a project where I need to create temp files.

I have a class that accepts a file path. and as needed it reads the data from the file. However, sometimes I have the data and I want to create the same object so I use tempfile. But I want the file to be deleted as the object garbage-collected.

This is my implementation which is wrong.

from pickle import load
import tempfile


class A:
    def __init__(self, file_path):
        self.file_path = file_path

    @property
    def data(self):
        with open(self.file_path, "rb") as f2r:
            return load(f2r)

    @classmethod
    def from_data(cls, data):
        with tempfile.NamedTemporaryFile() as tmp:
            tmp.write(data)
            return cls(tmp.name)

The from_data method creates the temp file and returns an object but the file will be deleted as soon as from_data returns the object. But I want the file to live until the object itself is garbage-collected.

4
  • Wouldn't it be more robust to turn A into a context manager, and close the tempfile as part of the exit from your context manager? Commented Sep 9, 2023 at 0:54
  • I see what you say. But this example is a pseudo example of a more complex project and the design cannot be changed like that. Commented Sep 9, 2023 at 1:01
  • 1
    What if you overrode the finalizer, __del__ so that it closes the tempfile when it is garbage collected? See also stackoverflow.com/questions/1481488/… Commented Sep 9, 2023 at 1:13
  • That's what I thought but I wanted to ask if there is a more elegant way to do so. But If you suggest so I'll implement it. Commented Sep 9, 2023 at 1:16

1 Answer 1

0

As @Nick ODell suggested I am going to use __del__ method to delete the file on garbage-collection.

So the code would look like:

from pathlib import Path
from pickle import load
import tempfile


class A:
    def __init__(self, file_path):
        self.file_path = file_path
        self.is_temp = False

    def __del__(self):
        if self.is_temp:
            Path(self.file_path).unlink()

    @property
    def data(self):
        with open(self.file_path, "rb") as f2r:
            return load(f2r)

    @classmethod
    def from_data(cls, data):
        with tempfile.NamedTemporaryFile(delete=False) as tmp:
            tmp.write(data)
            a = cls(tmp.name)
            a.is_temp = True
            return a
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.