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

时间:2009-06-29 11:35:00

标签: python python-import

我有一个带有__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')

的另一种方式

7 个答案:

答案 0 :(得分: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.

答案 1 :(得分:17)

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

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

事实上,此处只需要__name__

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

答案 2 :(得分: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 :(得分:3)

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

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

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

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

答案 4 :(得分:0)

你可以试试这个:

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

答案 5 :(得分:0)

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

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

import sites

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

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

答案 6 :(得分:0)

我知道这个问题是关于__import__()函数的,但是我认为importlib软件包最适合运行时软件包的导入,如果您使用{{ 3}}:

  

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

可能的陷阱:doc

  

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用于This was introduced in python 2.7:中所述的相对路径解析:

  

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