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

问题描述 投票:15回答:7

我有一个带有__init__.py文件的消息文件夹(包)和其中的另一个模块messages_en.py。在__init__.py,如果我导入messages_en它工作,但__import__失败“ImportError:没有模块名为messages_en”

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

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

python python-import
7个回答
19
投票

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

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

事实上,这里只需要__name__

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

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.

14
投票

__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


3
投票

确保将modules目录附加到python路径。

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

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

import sys
sys.path.append("/home/me/mypy") 

0
投票

你可以试试这个:

messages == __import__('Foo.messages_en', fromlist=['messages_en'])

0
投票

您需要手动导入动态包路径的顶级包。

例如,在我写的文件的开头:

import sites

然后在代码中,这对我有用:

target = 'some.dynamic.path'
my_module = __import__ ('sites.%s.fabfile' % target, fromlist=["sites.%s" % target])

0
投票

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

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

可能的问题:This was introduced in python 2.7:

版本2.7中的新功能。

此模块是Python 3.1中功能更全面的包中提供的一小部分,它提供了完整的导入实现。这里提供了什么来帮助轻松地从2.7过渡到3.1。

在您的情况下,您可以使用:

import importlib

messages = importlib.import_module('messages_en')

此外,如果要指定包名称,则from messages import messages_en可以写为:

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

请注意.中的.messages_en用于相对路径分辨率,如here所述:

... name参数指定以绝对或相对术语导入的模块(例如pkg.mod或..mod)。如果名称是以相对术语指定的,那么package参数必须设置为包的名称,该包用作解析包名的锚(例如import_module('.. mod','pkg.subpkg')将导入pkg.mod)。

© www.soinside.com 2019 - 2024. All rights reserved.