绝对导入模块在同一个包中

时间:2014-05-08 08:07:19

标签: python python-2.7 python-3.x import

我已将导入问题简化为这个简单的基本情况。说我有一个Python包:

mypkg/
   __init__.py
   a.py
   b.py

a.py包含:

def echo(msg):
    return msg

b.py包含:

from mypkg import a       # possibility 1, doesn't work
#import a                 # possibility 2, works
#from mypkg.a import echo  # import also fails

print(a.echo())

在Python 2.7.6和Python 3.3.5上运行python b.py会产生ImportError: No module named mypkg。我也尝试在两种情况下添加from __future__ import absolute_import,同样的问题。

预期:

我希望可能性1能够正常工作。

为什么我要这样做:

可能性2不太理想。假设标准库可以引入一个名为a的包(在这种情况下不太可能,但你明白了)。当Python 2搜索current package first时,Python 3+包含绝对导入更改,以便首先检查标准库。 不管我的理由是什么,可能性1应该起作用,不是吗?我可以发誓我以前做了好几千次。

注意:如果您在mypkg外部编写脚本,from mypkg import a可以正常运行。

我的问题类似于python - absolute import for module in the same directory,但作者暗示我所拥有的应该是有效的。

4 个答案:

答案 0 :(得分:11)

from mypkg import a是正确的表单。不要从Python包目录中运行脚本,它使用可能导致错误的多个名称使相同的模块可用。从包含python -m mypkg.b的目录运行mypkg

为了能够从任何目录运行,mypkg应该在pythonpath中。

答案 1 :(得分:0)

我认为问题来自于您在 mypkg 文件夹中没有引用 mypkg 这一事实。看一下当我尝试运行你的例子时Python正在做什么(使用详细选项):

# trying /vagrant/mypkg/mypkg.py

这就是为什么它可以找到模块,因为它不存在。你可以做的一件事是用一行名为 mypkg.py 的文件

import a

但这只是你在另一件夹克上面的第二个可能性。在不知道你想要完成什么的情况下,我会在Intra-package Reference文本中选择第一个例子。我会这样写 b.py

from a import echo

print(echo('message'))

答案 2 :(得分:0)

是的,它不起作用,因为在您调用print(mypkg.a.echo())的那一刻,mypkg仍在加载中(mypkg.__init__-> mypkg.b)。这是因为Python首先加载父模块。 https://docs.python.org/3/reference/import.html#searching

您可以做的是将print(mypkg.a.echo())包装到一个函数中:

def echo():
   mypkg.a.echo()

然后:

import mypkg.b
mypkg.b.echo()

甚至:

print(sys.modules['mypkg.a'].echo())

您还可以帮助Python查找模块:

import importlib
mypkg.a = importlib.import_module('mypkg.a')
mypkg.a.echo()

答案 3 :(得分:-1)

试试这个:

import sys
import os
this_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.dirname(this_dir))

from mypkg import a
print(a.echo())