dynamic module import?

Duncan Booth duncan.booth at invalid.invalid
Sun Jan 18 17:24:16 CET 2009


alex23 <wuwei23 at gmail.com> wrote:

> I must confess I've rarely had a need to use __import__ and don't
> think I've ever used the fromlist arg. I'm confused, though, because
> the docstring states:
> 
>  The fromlist should be a list of names to emulate ``from name
> import ...''
> 
> But it also states that __import__ always returns a module, so I'm
> utterly confused as to the purpose of fromlist, or how to inject the
> specified entries into the calling namespace. If anyone could explain
> this for me, I'd really appreciate it.

Compare these:

>>> dom =  __import__('xml').dom
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'dom'
>>> dom =  __import__('xml', fromlist=['dom']).dom
>>> dom
<module 'xml.dom' from 'C:\Python26\lib\xml\dom\__init__.pyc'>

Then in a new session:
>>> import xml
>>> xml.dom
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'dom'
>>> from xml import dom
>>> dom
<module 'xml.dom' from 'C:\Python26\lib\xml\dom\__init__.pyc'>
>>>

When you import a package such as xml it only imports the top level. 
Modules and subpackages within the imported package aren't available until 
they are explicitly imported. The fromlist argument to __import__ allows 
you to force the lower modules to also import.

>>> xml = __import__('xml', fromlist=['dom'])

is effectively the same as doing:

>>> import xml.dom

After either of these you have a name 'xml' which has an attribute 'dom':

>>> xml.dom
<module 'xml.dom' from 'C:\Python26\lib\xml\dom\__init__.pyc'>

To access the actual sub-objects using __import__ use getattr on the 
returned module. So far as injecting names into the calling namespace is 
concerned just assign to variables; you don't want to be injecting unknown 
names into your namespace.

For the same effect if you only have one name and you know it is a module 
you could do:

>>> xml = __import__('xml.dom')

but you need the fromlist parameter if you don't know which of the names 
are modules.



More information about the Python-list mailing list