Python相对导入一处不解

浮生若梦的编程
  • 2.8k

问题

代码目录是:

pkg
│  __init__.py
│
├─pkg1
│      module1.py
│      __init__.py
|      module3.py
│
└─pkg2
        module2.py
        __init__.py

尝试进行相对导入,绝对导入,均报对应错误 (所有操作均在module1.py这个文件中)

我确定自己仔细阅读了有关Python的导入问题的许多文章(特别是官方文档), 我觉得自己没有理解错误,我的理解是

  1. 该放__init__.py的地方就是一个Python包了

  2. 包可以绝对导入

  3. 包内可以相对导入

严重怀疑是其他方面的知识, 我没有阅读过

自己大部分时候都在IDE中编写Python代码,很少遇到导入问题(anyway, IDE反正是个黑盒子, 它做了许多工作), 但是Python的导入问题还是要搞清楚的

相关代码

  • module2.py

def add(a, b):
    return a + b
  • module1.py

############################
#          第一种. 绝对导入
############################
import sys
import os.path

p = os.path.abspath('.')
p = os.path.dirname(p)
if p not in sys.path:           #加入sys.path(不一定要加, 我是后来加上的,也报错)
    sys.path.append(p)
print(p)
print(sys.path)                #我都把pkg/添加到path中了,还不行,我就不解了!

from pkg.pkg2 import module2   # ImportError: No module named pkg.pkg2

##############################
#         另一种绝对导入(不把p导入到sys.path中)
##############################
from pkg.pkg2 import module2


############################
#         第二种
############################
from ..pkg2 import module2    # ValueError: Attempted relative import in non-package

##########################
#        第三种
#########################
from . import module3        # ValueError: Attempted relative import in non-package

重现

报错信息

相关截图

上下文环境

  1. Windows7

  2. Python2.7

  3. Sublime3

尝试解决

  1. 看了一些资料, 越发怀疑自己对这两种导入的理解了

回复
阅读 3.5k
2 个回答

解决了.

主要是要搞清楚,你的py程序从哪里开始运行的问题.

  1. 比如你有一个需要运行的文件,非常简单,可以直接python $pyfile

  2. 你有一个需要运行的py文件,恰好在一个包内,而且与该包内其他模块发生了互动,而此时你又恰好要运行它, 此时你python $pyfile,那么该文件作为入口,然后python去找包,自然会找不到. 那么以谁为入口呢? 答案是: pkg为入口. 所以要cd pkg的父目录, python -m pkg.pkg1.module1 (此时可以在module1.py中写各种导入,都是不会报错的)

  3. Python有自己一整套的导入机制,包机制,模块机制,需要仔细理解(我也不知道为什么要弄得这么复杂)

建议你看下我写的这篇博客http://www.cnblogs.com/piperc...
另外如果是项目,建议使用PYTHONPATH环境变量指定项目位置,方便进行绝对路径导入。

另外我复现了你上面问的问题 第一种绝对寻址可以通过

from pkg2 import module2

你写错了
另外第二种第三种为何不行我建议你参照这个回答 理解一下__name__ 和 __main__的问题
http://stackoverflow.com/ques...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏