Python的__import__不能按预期工作
-
03-07-2019 - |
题
当使用带有点名的 __ import __
时,如: somepackage.somemodule
,返回的模块不是 somemodule
,无论返回什么似乎大多是空的!这是怎么回事?
解决方案
来自 __ import __
:
__import__( name[, globals[, locals[, fromlist[, level]]]])
...
当name变量属于表单时 package.module,通常是 顶级包(名称直到 返回第一个点,而不是 按名称命名的模块。但是,当一个 给出了非空的fromlist参数, 返回按名称命名的模块。 这样做是为了兼容 为...生成的字节码 不同种类的进口声明; 当使用“import spam.ham.eggs”时, 必须放置顶级包垃圾邮件 在导入命名空间中,但何时 使用“from spam.ham import eggs”,the 必须使用spam.ham子包 找到蛋变量。作为一个 解决此问题的方法,使用 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
,这通常是空的。
如果你提供 fromlist
(你想要的 somemodule
里面的变量名列表,实际上没有返回),它将返回 somemodule
您也可以像我一样使用他们建议的功能。
注意:我问这个问题完全打算自己回答。我的代码中有一个很大的错误,并且误解了它,我花了很长时间才弄明白,所以我想我会帮助SO社区并发布我遇到的陷阱。
其他提示
python 2.7具有importlib,虚线路径按预期解析
import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()
有一个更简单的解决方案,如文档中所述:
如果您只想按名称导入模块(可能在包中),可以调用__import __()然后在sys.modules中查找:
>>> import sys
>>> name = 'foo.bar.baz'
>>> __import__(name)
<module 'foo' from ...>
>>> baz = sys.modules[name]
>>> baz
<module 'foo.bar.baz' from ...>
有些东西可以按照您的要求运行: 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'>
对于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
我的方式是
foo = __import__('foo', globals(), locals(), ["bar"], -1)
foobar = eval("foo.bar")
然后我可以访问
中的任何内容foobar.functionName()