如何动态导入包中模块的类?

2 投票
4 回答
1761 浏览
提问于 2025-04-16 03:21

这可能看起来很简单,但我不太明白。下面的代码可以正常工作:

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 模块。

撰写回答