Python disk caching with index My task is that of caching. If the folder exists then load the cache from disk, if it doesnt create new cache. This is trivial, what bothers me is if I want to create third mode of noop (don't do anything relating to cache).

Currently I have this:

class HeavyCalculationClass:
    def __init__(self, cache_dir=None)
        self.use_cache = cache_dir is not None
        if self.use_cache:
            if os.path.exists(cache_dir):
                if len(os.listdir(cache_dir) != 0:
                    self.cache_type = "write"
                else:
                    self.cache_type = "read"
            else:
                os.mkdir(cache_dir)
                self.cache_type = "write"

    def __getitem__(self, idx):
        if self.use_cache and self.cache_type=="read":
            data = numpy.load(os.path.join(cache_dir, str(idx)+".npy"))
        else:
            data = very_heavy_calculation()

        if self.use_cache and self.cache_type == "write":
            numpy.save(os.path.join(cache_dir, str(idx)+".npy"), data)
        return data


Is there any way to write this in a more elegant form?
I don't know what you mean by "more elegant", but I would recommend using pathlib.  This class provides for caching to be enabled/disabled for all files.  If the class is not initialized with a cache_dir, then caching is disabled.  If a cache_dir is provided, then __getitem__() loads data from cached files, if they exist.  Otherwise the data is calculated and cached.

class HeavyCalculationClass:
    def __init__(self, cache_dir=None):
        # sets the path to the cache directory if it was specified
        # and creates the cache directory if needed
        if cache_dir:
            self.cache = pathlib.Path(cache_dir)

            if not self.cache.is_dir():
                self.cache.mkdir()

        else:
            # empty cache path means ignore the cache
            self.cache = None

    def __getitem__(self, idx):
        # if caching is 'on' and this file is cached,
        # then load it
        if self.cache:
            cache_file = self.cache / f"{idx}.npy"

            if cache_file.is_file():
                data = numpy.load(cache_file))
                return data

        # otherwise calculate the data
        data = very_heavy_calculation()

        # cache the data if a cache path is set
        if self.cache:
            numpy.save(self.cache / f"{idx}.npy"), data)

        return data