当包名称仅在运行时已知时,如何使用__import __()导入包?

Anu*_*yal 15 python python-import

我有一个带__init__.py文件的消息文件夹(包)和messages_en.py里面的另一个模块.在__init__.py如果我导入messages_en它的工作原理,但__import__失败,"导入错误:没有模块名为messages_en"

import messages_en # it works
messages = __import__('messages_en') # it doesn't ?
Run Code Online (Sandbox Code Playgroud)

我曾经认为'import x'只是另一种说法 __import__('x')

wr.*_*wr. 19

如果是路径问题,您应该使用level参数(来自docs):

__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.
Run Code Online (Sandbox Code Playgroud)

  • 但我想知道是什么原因,因为默认级别是-1,我仍然传递-1,所以只有额外的全局/本地词典,这有什么区别 (2认同)
  • 在 Python 3 中,级别必须 >=0。在这种情况下将其设置为 1。 (2认同)

Eri*_*ric 19

添加globals参数对我来说已经足够了:

__import__('messages_en', globals=globals())
Run Code Online (Sandbox Code Playgroud)

事实上,__name__这里只需要:

__import__('messages_en', globals={"__name__": __name__})
Run Code Online (Sandbox Code Playgroud)


Per*_*vic 14

__import__是import语句调用的内部函数.在日常编码中,您不需要(或不想)打电话__import__

来自python文档:

例如,语句import spam导致字节码类似于以下代码:

spam = __import__('spam', globals(), locals(), [], -1)
Run Code Online (Sandbox Code Playgroud)

另一方面,声明from spam.ham import eggs, sausage as saus导致

_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1)
eggs = _temp.eggs
saus = _temp.sausage
Run Code Online (Sandbox Code Playgroud)

更多信息:http: //docs.python.org/library/functions.html


小智 5

请务必将模块目录附加到您的 python 路径。

您的路径(Python 搜索模块和文件时所经过的目录列表)存储在 sys 模块的 path 属性中。由于路径是一个列表,因此您可以使用追加方法将新目录添加到路径中。

例如,要将目录 /home/me/mypy 添加到路径中:

import sys
sys.path.append("/home/me/mypy") 
Run Code Online (Sandbox Code Playgroud)

  • 这是不安全的,因为它使包无法重新定位。仅当包位于此硬编码路径中时它才有效。 (2认同)

Chu*_*eka 5

我知道这个问题是关于__import__()函数的,但我认为如果您按照文档importlib中的建议使用 Python 2.7 或更高版本,则该包最适合运行时包导入:

注意:以编程方式导入模块应使用 import_module() 而不是此函数。

可能的问题:这是在 python 2.7 中引入的:

2.7 版本中的新功能。

该模块是 Python 3.1 中功能更齐全的同名包中可用模块的一个小子集,该包提供了导入的完整实现。此处提供的内容旨在帮助轻松从 2.7 过渡到 3.1。

根据您的情况,您可以使用:

import importlib

messages = importlib.import_module('messages_en')
Run Code Online (Sandbox Code Playgroud)

另外,如果你想指定包名,那么from messages import messages_en可以写成:

importlib.import_module('.messages_en', 'messages')

请注意用于相对路径解析的.in ,如下所述.messages_en

... name 参数指定以绝对或相对方式导入哪个模块(例如 pkg.mod 或 ..mod)。如果以相对术语指定名称,则必须将 package 参数设置为包的名称,该包的名称将充当解析包名称的锚点(例如 import_module('..mod', 'pkg.subpkg')将导入 pkg.mod)。