Python import as global name not defined
global, import, python, python-import
Solution
In Python, each module has it's own global namespace. When you do an import, you're only adding the imported modules to the current module's namespace, not to the namespace of any other module. If you want to put it in another namespace, you need to tell Python this explicitly.
main.py:
if db == "mysql": # or whatever your real logic is
import mysql_db as db_util
elif db == "postgres":
import postgres_db as db_util
import some_helper_module
some_helper_module.db_util = db_util # explicitly add to another namespace
#...
Other modules:
import some_helper_module
db = some_helper_module.db_util.connect() # or whatever the real API is
#...
Note that you can't usually use your main module (which is executed as a script) as a shared namespace. That's because Python uses the module's `__name__` attribute to determine how to cache the module (so that you always get the same object from multiple imports), but a script is always given a `__name__` of `"__main__"` rather than its real name. If another module imports `main`, they'll get a separate (duplicate) copy!
Problem
I have an application that runs on Postgres & Mysql. Each program checks to determine the database and then imports either postgres_db as db_util or mysql_dt as db_util. All works well when code in main references db_util, but if a class is imported, the reference to db_util is not defined. I created the following to classes and main to test the problem and found another interesting side effect. Classes B & C reference ClassA under different import cases. B & C are identical except B is in main and C is imported. ClassX.py ``` class ClassA(object): def print_a(self): print "this is class a" class ClassC(object): def ref_a(self): print 'from C ref a ==>', xa=ClassA() xa.print_a() def ref_ca(self): print 'from C ref ca ==>', xa=ca() xa.print_a() ``` test_scope.py ``` from classes.ClassX import ClassA from classes.ClassX import ClassA as ca from classes.ClassX import ClassC as cb class ClassB(object): def ref_a(self): print 'from B ref a ==>', xa=ClassA() xa.print_a() def ref_ca(self): print 'from B ref ca ==>', xa=ca() xa.print_a() print 'globals:',dir() print 'modules','ca:',ca,'cb:',cb,'CA:',ClassA print '' print 'from main' xb=ClassB() xb.ref_a() xb.ref_ca() print '' print 'from imports' xbs=cb() xbs.ref_a() xbs.ref_ca() ``` And the results: ``` globals: ['ClassA', 'ClassB', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'ca', 'cb'] modules ca: <class 'classes.ClassX.ClassA'> cb: <class 'classes.ClassX.ClassC'> CA: <class 'classes.ClassX.ClassA'> from main from B ref a ==> this is class a from B ref ca ==> this is class a from imports from C ref a ==> this is class a from C ref ca ==> Traceback (most recent call last): File "test_scope.py", line 32, in <module> xbs.ref_ca() File "R:\python\test_scripts\scope\classes\ClassX.py", line 13, in ref_ca xa=ca() NameError: global name 'ca' is not defined Press any key to continue . . . ``` From my test, I see that the object ca (imported as) is not available to the ClassC, however, the module ClassA is available (imported without as). - Why the difference between import and import as behavior? I am unclear why mains globals are not available to classes main imports. - What is a good approach to dynamically determine appropriate db_util module to import and have it accessible to other imported classes? Update: After reading yet another post on Namespaces: "Visibility of global variables from imported modules", I understand that in my example above the reason classA is available to ClassC is that A & C are in the same imported file, thus the same namespace. So the remaining question is a design question: if I have code like this: ``` if db == 'MySQL': from mysql_db import db_util elif db == 'Postgres' from postgres_db import db_util ``` What is a good approach to make db_util available to all imported modules? UPDATE: from the reponse by Blckknght, I added the code ``` cb.ca =ca ``` to the scope_test script. This requires the class call to xa=ca() be changed to xa=self.ca(). I also think that adding objects to a class from outside the class, though Python allows it, is not a good design methodology and will make debugging a nightmare. However, since I think modules and classes should be standalone or specifically declare their dependencies, I am going to implement the class like this, using the code sample from above. break out ClassA and ClassC to separate modules and at the top of ClassC, before the class definition, do the imports ``` from ClassA import ClassA from ClassA import ClassA as ca class ClassB(object): ``` and in my real situation, where I need to import the db_util module into several modules ci.py #new module to select class for appropriate db ``` if db == 'MySQL': from mysql_db import db_util elif db == 'Postgres' from postgres_db import db_util ``` in each module needing the db_util class ``` import ci db_util=ci.db_util #add db_util to module globals class Module(object): ``` One problem with this is it requires each module using the db_util to import it, but it does make the dependencies known. I will close this question and want to thank Blckknght and Armin Rigo for their responses which help clarify this issue for me. I would appreciate any design related feedback.