Coder1
Coder1

Reputation: 13321

Globals across modules

Wow, this seems so basic, but I can't get it to work. All I need to do is store a global dict which can be accessed and modified from other modules & threads.

What's the "best practices" way of achieving this?

test.py

import testmodule

class MyClassA():
    def __init__(self, id):
        self.id = id

if __name__ == '__main__':
    global classa_dict
    classa_dict = {}
    classa_dict[1] = MyClassA(1)
    classa_dict[2] = MyClassA(2)

    testing = testmodule.TestModule()

testmodule.py

class TestModule():
    def __init__(self):
        global classa_dict
        print classa_dict[2]

output

$ python test.py 
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    testing = testmodule.TestModule()
  File "/path/to/project/testmodule.py", line 4, in __init__
    print classa_dict[2]
NameError: global name 'classa_dict' is not defined

Upvotes: 0

Views: 176

Answers (2)

phimuemue
phimuemue

Reputation: 35983

You can in fact acchieve something like what you want:

testmodule.py:

classa_dict={}

class Test():
    def __init__(self):
        global classa_dict
        print classa_dict[2]

test.py:

import testmodule

class MyClassA():
    def __init__(self, id):
        self.id = id

if __name__ == '__main__':
    lclassa_dict = testmodule.classa_dict
    lclassa_dict[1] = MyClassA(1)
    lclassa_dict[2] = MyClassA(2)

    testing = testmodule.Test()

Please note that global is used somewhat else than what you might think of. If you write global varname, this means, that Python should not generate a local variable varname, but look in the global scope for a variable named varname. That is, the class Test does not generate a local variable classa_dict, but it uses the global variably classa_dict instead.

So, global is nothing to give at declaration to tell python that the variable can be used everywhere. It much more tells Python that there is already some variable with this name, that is referred to.

This means, in testmodule.ty the line global classa_dict means: Look somewhere in the module to find a variable classa_dict and operate on this variabla instead of creating a new local variable classa_dict.

In test.py, then you can assign classa_dict = testmodule.classa_dict which tells python that lclassa_dict refers to the classa_dict in testmodule.py. Therefore, you don't need a global in test.py, because, you simply modify testmodule.classa_dict when you assign something to lclassa_dict. Then, the class Test in testmodule.py knows that it should look to testmodule.classa_dict because it uses the global.

Upvotes: 2

Daniel Roseman
Daniel Roseman

Reputation: 599490

The best practice is not to do this at all.

The global keyword is really misnamed - it just means module scope, rather than local. There's no way to have a variable that's in every scope automatically. Instead, define it at the module level in one module and import it wherever you need it.

Upvotes: 4

Related Questions