4
\$\begingroup\$

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?

| improve this question | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Could you provide more code, currently the way I think would be an improvement could just be a hindrance. \$\endgroup\$ – Peilonrayz Mar 16 at 21:58
  • \$\begingroup\$ @Peilonrayz I've tried but adding any other code would just complicate too much, and won't focus on the core issue. Could you post your thoughts as an answer? Pretty much it needs to be iterable (hence getitem) , and if the file already exists on disk, just skip heavy calculation and read from disk. \$\endgroup\$ – Dusan J. Mar 17 at 9:13
  • \$\begingroup\$ Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles. \$\endgroup\$ – Toby Speight Mar 17 at 9:52
  • \$\begingroup\$ @TobySpeight I've edited it but I'm not sure how to name it precisely. Trying to optimize for easy recognition for someone who's done similar stuff but like this it is too specific and the same problem can be experienced with other stuff (not necesseraly caching). \$\endgroup\$ – Dusan J. Mar 17 at 10:19
  • 1
    \$\begingroup\$ Looks better now! :-) \$\endgroup\$ – Toby Speight Mar 17 at 11:08
5
\$\begingroup\$

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
| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ more elegant as in less lines of code less variables, simpler to read \$\endgroup\$ – Dusan J. Mar 17 at 9:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.