13

I create a dictionary from a remote database as part of my application run. This process is pretty I/O heavy, so I've decided to create a "singleton" instance of this dictionary and just call it as it is needed in my application.

The code looks like (in Dictionaries.py):

state_code_dict = None

def get_state_code_dict():
    global state_code_dict
    if state_code_dict == None:
        state_code_dict = generate_state_code_dict()
    return state_code_dict

I then import and call the get_state_code_dict() function where needed. I added a print statement to check if state_code_dict was being reinitialized or reused, and I found it was being reused (which is the functionality I want). Why is the instance of state_code_dict surviving the application run?

Edit

I import the get_state_code_dict function in multiple files.

Tyler DeWitt
  • 23,366
  • 38
  • 119
  • 196
  • because imported code gets executed only the first time? – KurzedMetal Jun 07 '12 at 17:29
  • edited to clarify: I import the code in multiple locations (multiple files include the `get_state_code_dict` function. – Tyler DeWitt Jun 07 '12 at 17:32
  • 1
    Importing code that the interpreter has already loaded will not re-load that code by default. It's possible to deliberately reload a module but if you have to do this for any reason other than because the actual code of the module might have changed during runtime, you should probably use a different programming idiom to do what you want to do. – Andrew Gorcester Jun 07 '12 at 17:35
  • And this behavior is desirable precisely because module initialization is sometimes heavyweight. – Russell Borogove Jun 07 '12 at 17:40

2 Answers2

24

This is the Python Language Reference's description of how importing a module works:

(1) find a module, and initialize it if necessary; (2) define a name or names in the local namespace

(Emphasis added.) Here, initializing a module means executing its code. This execution is only performed if necessary, i.e. if the module was not previously imported in the current process. Since Python modules are first-class runtime objects, they effectively become singletons, initialized at the time of first import.

Note that this means that there's no need for a get_state_dict_code function; just initialize state_code_dict at top-level:

state_code_dict = generate_state_code_dict()

For a more in-depth explanation, see this talk by Thomas Wouters, esp. the first part — around 04:20 — where he discusses the "everything is runtime" principle.

martineau
  • 119,623
  • 25
  • 170
  • 301
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
14

I voted larsmans answer, i just wanted to add an example.

hello.py:

hi = 'hello'

print(hi)

def print_hi():
    print(hi)

ipython session:

In [1]: from hello import print_hi
hello

In [2]: print_hi()
hello

In [3]: from hello import print_hi

In [4]: import hello

In [5]: hello.print_hi()
hello


Look that the imports at lines 3 and 4 don't output "hello" as the import in line 1 did, that means the code isn't re-executed.

MicronXD
  • 2,190
  • 16
  • 24
KurzedMetal
  • 12,540
  • 6
  • 39
  • 65