How to import from within a module

David Bolen db3l at fitlinxx.com
Fri Dec 29 14:11:41 EST 2000


Le Snelson <le_snelson at transtechinc.cc> writes:

> I am attempting to import a module from in a function within a sort of
> root module [init] - it contains only an initialization function.  The
> intent is that configuration files will provide data to derive the name
> of the module to be imported. All of the scripts provide the same
> function names but for different underlying devices.
> 
> I am unable to get __import__( xxx ) to actually add xxx to any visible
> dictionary. However, in the same file if I uncomment a line at the top
> (global scope) that reads:
> import xxx
> Sure enough the xxx is in the list from dir(init).

The "import xxx" statement both imports the module (or finds it in
sys.modules if it has already been loaded), but also acts as a
definition in the local namespace for that module using it's name.  So
"import xxx" both finds/loads module xxx, and then sets a label "xxx"
to reference that module.

When you use "__import__" it just returns a reference to the loaded
module, but doesn't change your namespace.  If you want to keep the
reference, you need to handle your own assignment.  So, typically,
using "__import__" to mimic "import" would be:

    xxx = __import__('xxx')

Note that in both cases, the label created is in the local namespace,
which might lead to some confusion if the import is done within a
function but you expect to use the module elsewhere.  While the module
itself will be loaded (and could be found in sys.modules), no
reference will exist outside of the namespace where the reference was
created.  For example, if in your init module you had:

    def somefunction():

	import xxx

	# Use xxx here
	xxx.otherfunction()


    # Call the function
    somefunction()

    # xxx is not a variable here - this gives a NameError on xxx
    xxx.otherfunction()


If you needed the module reference to be available in both places, you
could either import it normally in the global scope (which the
somefunction() reference would then find), or you could import it
later in the module just above when your global scope needed it.  The
later import would just reference the existing copy in sys.modules,
creating the reference to it.  (You could actually achieve the same
thing with "xxx = sys.modules['xxx']" but unless you were sure it had
previously been imported, you'd want to protect that sys.modules
reference against a KeyError).

If the issue is that somefunction() is dynamically figuring out what
module to load (thus you can't just import it in global module scope),
and then you want to insert it into the module level scope while still
within the function, that gets trickier.  It's probably cleaner to
have the function return a reference to the module which the caller
(from the module level scope) uses to assign to the variable.  There
have been other posts in this newsgroup covering accessing your own
module's dictionary to make such modifications, or explicitly
installing such references in the global scope, if that's really what
you want to do.

--
-- David
-- 
/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l at fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/



More information about the Python-list mailing list