简体   繁体   English

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

[英]Absolute import module in same package

I've simplified my import problems down to this simple base case. 我将导入问题简化为这个简单的基本情况。 Say I have a Python package: 说我有一个Python包:

mypkg/
   __init__.py
   a.py
   b.py

a.py contains: a.py包含:

def echo(msg):
    return msg

b.py contains: 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())

Running python b.py produces ImportError: No module named mypkg on both Python 2.7.6 and Python 3.3.5. 运行python b.py会产生ImportError: No module named mypkg在Python 2.7.6和Python 3.3.5上都ImportError: No module named mypkg I have also tried adding from __future__ import absolute_import in both cases, same issue. 我也尝试在两种情况下from __future__ import absolute_import添加,同样的问题。

Expected: 预期:

I expect possibility 1 to work just fine. 我希望可能性1工作得很好。

Why do I want to do this: 为什么我要这样做:

Possibility 2 is less desirable. 可能性2不太理想。 Hypothetically, the standard library could introduce a package called a (unlikely in this case, but you get the idea). 假设,标准库可以引入一个名为a的包(在这种情况下不太可能,但你明白了)。 While Python 2 searches the current package first , Python 3+ includes absolute import changes so that the standard library is checked first. 虽然Python 2首先搜索当前包 ,但Python 3+包含绝对导入更改,因此首先检查标准库。 No matter what my reason, possibility 1 is supposed to work, no? 不管我的理由是什么,可能性1应该起作用,不是吗? I could swear I've done it thousands of times before. 我可以发誓,我以前做过几千次。

Note: If you write a script external to mypkg , from mypkg import a works without issue. 注意:如果您在mypkg外部编写脚本, from mypkg import a正常工作。

My question is similar to python - absolute import for module in the same directory , but the author implies that what I have should be working. 我的问题类似于python - 在同一目录中对模块进行绝对导入 ,但作者暗示我所拥有的应该是正常的。

from mypkg import a is the correct form. from mypkg import a是正确的表单。 Don't run scripts from inside the Python package directory, it makes the same module available using multiple names that may lead to bugs. 不要从Python包目录中运行脚本,它使用可能导致错误的多个名称使相同的模块可用。 Run python -m mypkg.b from the directory that contains mypkg instead. 从包含mypkg的目录运行python -m mypkg.b

To be able to run from any directory, mypkg should be in pythonpath. 为了能够从任何目录运行, mypkg应该在pythonpath中。

Try this: 尝试这个:

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())

I think the problem comes from the fact that you don't have a reference to mypkg inside the mypkg folder. 我认为问题来自于mypkg文件夹中没有对mypkg的引用。 Look at what Python is doing when I try to run your example (using the verbose option): 看一下当我尝试运行你的例子时Python正在做什么(使用verbose选项):

# trying /vagrant/mypkg/mypkg.py

That's why it can find the module, because it doesn't exist. 这就是为什么它可以找到模块,因为它不存在。 One hack you could do is to have a file called mypkg.py with the line 你可以做的一件事是用一行名为mypkg.py的文件

import a

but that's just your 2nd possibility above in another jacket. 但这只是你在另一件夹克上面的第二种可能性。 Without knowing what you want to accomplish, I would choose the first example on the Intra-package Reference text. 在不知道您想要完成什么的情况下,我会选择Intra-package Reference文本中的第一个示例。 I would write b.py as such: 我会这样写b.py

from a import echo

print(echo('message'))

Yes it will not work, because at the moment you call print(mypkg.a.echo()) , mypkg is still loading ( mypkg.__init__ -> mypkg.b ). 是的,它不起作用,因为在你调用print(mypkg.a.echo())mypkg仍在加载( mypkg.__init__ - > mypkg.b )。 This is because Python loads parent modules first. 这是因为Python首先加载父模块。 https://docs.python.org/3/reference/import.html#searching https://docs.python.org/3/reference/import.html#searching

What you can do is wrap print(mypkg.a.echo()) into a function: 你可以做的是将print(mypkg.a.echo())包装到一个函数中:

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

And then: 接着:

import mypkg.b
mypkg.b.echo()

Or even: 甚至:

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

Also you can help Python to find your module: 您也可以帮助Python找到您的模块:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM