如何动态导入包中模块的类?
这可能看起来很简单,但我不太明白。下面的代码可以正常工作:
foo.py
class Foo:
pass
bar.py
module = __import__('foo')
foo = module.__dict__['Foo']
之后,foo
就是我们预期的类 foo.Foo
。
但是,如果我把 a.py
放到一个包里,它就不工作了:
qux/__init__.py
(空文件)
qux/foo.py
class Foo:
pass
bar.py
module = __import__('qux.foo')
foo = module.__dict__['Foo']
运行 python bar.py
会出现 KeyError: 'Foo'
的错误,但模块导入还是成功的。
这是怎么回事,我该怎么才能让它正常工作呢?
4 个回答
2
你可以直接使用 importlib
来访问一个模块,无论它是嵌套的还是不嵌套的:
import importlib
module_name="qux.foo"
mod=importlib.import_module(module_name)
想了解更多细节,可以查看 http://docs.python.org/dev/library/importlib.html。
3
__import__
用于嵌套模块名称时,会返回最顶层的模块或包,这里就是 qux
。不过,所有的模块都会被放到 sys.modules
这个地方,所以你可以直接在里面查找 qux.foo
。
想了解更多,可以看看 __import__()
的官方文档,里面有详细的说明。
3
如果你想导入一个子模块,可以这样做:
package = __import__('qux', fromlist=['foo'])
module = getattr(package, 'foo')
需要注意的是,当使用 fromlist
时,__import__
会返回第一个参数中最里面的名称。所以你可以在 __import__
的调用中替换成 baz.bar.qux
来访问 baz.bar.qux.foo
模块。