如何在运行时动态导入包?

17 投票
7 回答
43660 浏览
提问于 2025-04-15 12:33

我有一个叫做messages的文件夹(包),里面有一个__init__.py文件,还有一个模块messages_en.py。在__init__.py里,如果我用普通的方式导入messages_en,那是没问题的,但如果我用__import__去导入,就会报错,提示“ImportError: No module named messages_en”。

import messages_en # it works
messages = __import__('messages_en') # it doesn't ?

我以前以为'import x'只是__import__('x')的另一种说法。

7 个回答

15

__import__ 是一个内部函数,它是由 import 语句调用的。在日常编程中,你不需要(也不想)直接调用 __import__

根据 Python 文档的说明:

比如,语句 import spam 会生成类似下面的字节码:

spam = __import__('spam', globals(), locals(), [], -1)

另一方面,语句 from spam.ham import eggs, sausage as saus 会生成:

_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1)
eggs = _temp.eggs
saus = _temp.sausage

更多信息可以查看这里:

http://docs.python.org/library/functions.html

22

如果这是一个路径问题,你应该使用 level 这个参数(可以参考 文档):

__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module

Level is used to determine whether to perform
absolute or relative imports.  -1 is the original strategy of attempting
both absolute and relative imports, 0 is absolute, a positive number
is the number of parent directories to search relative to the current module.
21

对我来说,添加globals这个参数就足够了:

__import__('messages_en', globals=globals())

实际上,这里只需要__name__就可以了:

__import__('messages_en', globals={"__name__": __name__})

撰写回答