Python import as global name not defined -


i have application runs on postgres & mysql. each program checks determine database , imports either postgres_db db_util or mysql_dt db_util. works when code in main references db_util, if class imported, reference db_util not defined.

i created following classes , main test problem , found interesting side effect. classes b & c reference classa under different import cases. b & c identical except b in main , c imported.

classx.py

class classa(object):     def print_a(self):         print "this class a"  class classc(object):     def ref_a(self):         print 'from c ref  ==>',         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 classes.classx import classa ca classes.classx import classc cb   class classb(object):     def ref_a(self):         print 'from b ref  ==>',         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 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'>  main b ref  ==> class b ref ca ==> class  imports c ref  ==> class 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' not defined press key continue . . . 

from test, see object ca (imported as) not available classc, however, module classa available (imported without as).

  1. why difference between import , import behavior? unclear why mains globals not available classes main imports.
  2. what approach dynamically determine appropriate db_util module import , have accessible other imported classes?

update: after reading yet post on namespaces: "visibility of global variables imported modules", understand in example above reason classa available classc & c in same imported file, same namespace.

so remaining question design question:

if have code this:

if db == 'mysql':     mysql_db import db_util elif db == 'postgres'     postgres_db import db_util 

what approach make db_util available imported modules?

update:

from reponse blckknght, added code

cb.ca =ca 

to scope_test script. requires class call xa=ca() changed xa=self.ca(). think adding objects class outside class, though python allows it, not design methodology , make debugging nightmare.

however, since think modules , classes should standalone or declare dependencies, going implement class this, using code sample above.

break out classa , classc separate modules , @ top of classc, before class definition, imports

from classa import classa classa import classa ca  class classb(object): 

and in real situation, need import db_util module several modules

ci.py #new module select class appropriate db

if db == 'mysql':     mysql_db import db_util elif db == 'postgres'     postgres_db import db_util 

in each module needing db_util class

import ci db_util=ci.db_util         #add db_util module globals  class module(object): 

one problem requires each module using db_util import it, make dependencies known.

i close question , want thank blckknght , armin rigo responses clarify issue me. appreciate design related feedback.

in python, each module has it's own global namespace. when import, you're adding imported modules current module's namespace, not namespace of other module. if want put in namespace, need tell python explicitly.

main.py:

if db == "mysql": # or whatever real logic     import mysql_db db_util elif db == "postgres":     import postgres_db db_util  import some_helper_module  some_helper_module.db_util = db_util # explicitly add namespace  #... 

other modules:

import some_helper_module  db = some_helper_module.db_util.connect() # or whatever real api  #... 

note can't use main module (which executed script) shared namespace. that's because python uses module's __name__ attribute determine how cache module (so same object multiple imports), script given __name__ of "__main__" rather real name. if module imports main, they'll separate (duplicate) copy!


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -