Python的__import__不能按预期工作

dwe*_*ook 43 python python-import

当使用__import__带点名称时,类似于:somepackage.somemodule,返回的模块不是somemodule,返回的任何内容似乎都是空的!这里发生了什么?

dwe*_*ook 54

从python文档__import__:

__import__( name[, globals[, locals[, fromlist[, level]]]])
Run Code Online (Sandbox Code Playgroud)

...

当name变量的形式为package.module时,通常会返回顶级包(直到第一个点的名称),而不是按名称命名的模块.但是,当给出非空的fromlist参数时,将返回按名称命名的模块.这样做是为了兼容为不同类型的import语句生成的字节码; 当使用"import spam.ham.eggs"时,顶级包垃圾邮件必须放在导入命名空间中,但是当使用"from spam.ham import eggs"时,必须使用spam.ham子包来查找egg变量.作为此行为的变通方法,请使用getattr()来提取所需的组件.例如,您可以定义以下帮助程序:

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

换句话说:

当你要求somepackage.somemodule,__import__返回时somepackage.__init__.py,往往是空的.

它将返回somemodule如果提供fromlist(变量名的名单里somemodule你想要的,实际上不返回)

您也可以像我一样使用他们建议的功能.

注意:我问这个问题完全打算自己回答.我的代码中有一个很大的错误,并且误解了它,我花了很长时间才弄明白,所以我想我会帮助SO社区并发布我遇到的问题.


cer*_*ros 32

python 2.7有importlib,虚线路径按预期解析

import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()
Run Code Online (Sandbox Code Playgroud)

  • 还有一个python 2.6软件包,它支持这个功能.https://pypi.python.org/pypi/importlib/ (2认同)

小智 16

有一个更简单的解决方案,如文档中所述:

如果您只想按名称导入模块(可能在包中),可以调用__import __()然后在sys.modules中查找:

>>> import sys
>>> name = 'foo.bar.baz'
>>> __import__(name)
<module 'foo' from ...>
>>> baz = sys.modules[name]
>>> baz
<module 'foo.bar.baz' from ...>
Run Code Online (Sandbox Code Playgroud)


Gly*_*yph 7

有些东西可以按照您的要求运行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'>
Run Code Online (Sandbox Code Playgroud)