Python __import__ not working properly

When using __import__ with the exact name, for example: somepackage.somemodule , the returned module is not somemodule , everything that is returned seems to be mostly empty! what's going on here?

+42
python python-import
Oct 17 '08 at 4:46
source share
6 answers

In python docs on __import__ :

 __import__( name[, globals[, locals[, fromlist[, level]]]]) 

...

If the name variable is of the form package.module, it is usually a top-level package (name to the first dot), and not a module by name. However, when a non-empty fromlist argument is given, a module with a name by name is returned. This is done for compatibility with the bytecode generated for various types of import applications; when using "import spam.ham.eggs", the top-level package spam should be placed in the namespace import, but when using "from spam.ham import eggs", the spam.ham subfolder should be used to find variable eggs. As a workaround for this behavior, use getattr () to retrieve the desired component. For example, you could define the following helper:

 def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod 

To rephrase:

When you request somepackage.somemodule , __import__ returns somepackage.__init__.py , which is often empty.

It will return somemodule if you provide fromlist (a list of variable names inside somemodule that you want that are not actually returned)

You can also use the feature they offer.

Note. I asked this question, fully intending to answer it myself. There was a big mistake in my code, and having mistakenly indicated it, it took me a long time to figure it out, so I decided that I would help the SO community and publish the information received here.

+53
Oct 17 '08 at 4:46
source share

python 2.7 has importlib dotted paths resolve as expected

 import importlib foo = importlib.import_module('a.dotted.path') instance = foo.SomeClass() 
+32
Feb 28 '11 at 6:08
source share

There is a simpler solution, as described in the documentation:

If you just want to import a module (potentially inside a package) by name, you can call __import __ () and then view it in sys.modules:

 >>> import sys >>> name = 'foo.bar.baz' >>> __import__(name) <module 'foo' from ...> >>> baz = sys.modules[name] >>> baz <module 'foo.bar.baz' from ...> 
+16
Aug 05 2018-11-11T00:
source share

There is something that works the way you want: twisted.python.reflect.namedAny :

 >>> from twisted.python.reflect import namedAny >>> namedAny("operator.eq") <built-in function eq> >>> namedAny("pysqlite2.dbapi2.connect") <built-in function connect> >>> namedAny("os") <module 'os' from '/usr/lib/python2.5/os.pyc'> 
+7
Oct 18 '08 at 6:37
source share

For python 2.6, I wrote this snippet:

 def import_and_get_mod(str, parent_mod=None): """Attempts to import the supplied string as a module. Returns the module that was imported.""" mods = str.split('.') child_mod_str = '.'.join(mods[1:]) if parent_mod is None: if len(mods) > 1: #First time this function is called; import the module #__import__() will only return the top level module return import_and_get_mod(child_mod_str, __import__(str)) else: return __import__(str) else: mod = getattr(parent_mod, mods[0]) if len(mods) > 1: #We're not yet at the intended module; drill down return import_and_get_mod(child_mod_str, mod) else: return mod 
+1
Mar 30 '11 at 17:07
source share

How i did it

 foo = __import__('foo', globals(), locals(), ["bar"], -1) foobar = eval("foo.bar") 

then I can access any content using

 foobar.functionName() 
0
Aug 19 '14 at 11:11
source share



All Articles