43

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

4

6 回答 6

54

来自 python 文档__import__

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

...

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

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

转述:

当您要求时somepackage.somemodule__import__返回somepackage.__init__.py通常是空的。

somemodule如果您提供,它将返回fromlist(您想要的变量名称列表,somemodule实际上并未返回)

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

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

于 2008-10-17T04:46:20.680 回答
32

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

import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()
于 2011-02-28T06:08:46.463 回答
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 ...>
于 2011-08-05T13:54:49.350 回答
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'>
于 2008-10-18T06:37:19.113 回答
1

对于 python 2.6,我写了这个片段:

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
于 2011-03-30T17:07:40.503 回答
0

我做的方式是

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

然后我可以访问任何内容

foobar.functionName()
于 2014-08-19T11:11:58.347 回答