2

I have a dictionary called fsdata at module level (like a global variable).

The content gets read from the file system. It should load its data once on the first access. Up to now it loads the data during importing the module. This should be optimized.

If no code accesses fsdata, the content should not be read from the file system (save CPU/IO).

Loading should happen, if you check for the boolean value, too:

if mymodule.fsdata:
    ... do_something()

Update: Some code already uses mymodule.fsdata. I don't want to change the other places. It should be variable, not a function. And "mymodule" needs to be a module, since it gets already used in a lot of code.

guettli
  • 25,042
  • 81
  • 346
  • 663
  • I'd derive from `dict`, do the lazy loading in the new class and override the `_bool__()` method, so that it if you use it in an `if`, it gets loaded, too. – phipsgabler Jun 15 '12 at 08:36
  • Does it _have_ to be a variable/property (and not a function)? – georg Jun 15 '12 at 08:49
  • 1
    see also: http://stackoverflow.com/questions/1462986/lazy-module-variables-can-it-be-done – georg Jun 15 '12 at 08:51
  • @thg435 thank you for the link. I voted to close my own question, since it is a duplicate. – guettli Jul 05 '12 at 07:26

3 Answers3

3

I think you should use Future/Promise like this https://gist.github.com/2935416

Main point - you create not an object, but a 'promise' about object, that behave like an object.

Sergey Miryanov
  • 1,820
  • 16
  • 29
2

You can replace your module with an object that has descriptor semantics:

class FooModule(object):
    @property
    def bar(self):
        print "get"
import sys
sys.modules[__name__] = FooModule()

Take a look at http://pypi.python.org/pypi/apipkg for a packaged approach.

ecatmur
  • 152,476
  • 27
  • 293
  • 366
1

You could just create a simple function that memoizes the data:

fsdata = []

def get_fsdata:
    if not fsdata:
        fsdata.append(load_fsdata_from_file())
    return fsdata[0]

(I'm using a list as that's an easy way to make a variable global without mucking around with the global keyword).

Now instead of referring to module.fsdata you can just call module.get_fsdata().

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895