任何人都可以解释python的相对进口吗?

car*_*arl 165 python

我不能为我的生活得到python的相对导入工作.我创建了一个它不起作用的简单示例:

目录结构是:

/__init__.py
/start.py
/parent.py
/sub/__init__.py
/sub/relative.py
Run Code Online (Sandbox Code Playgroud)

/start.py 仅包含: import sub.relative

/sub/relative.py 只包含 from .. import parent

所有其他文件都是空白的.

在命令行上执行以下操作时:

$ cd /
$ python start.py
Run Code Online (Sandbox Code Playgroud)

我明白了:

Traceback (most recent call last):
  File "start.py", line 1, in <module>
    import sub.relative
  File "/home/cvondrick/sandbox/sub/relative.py", line 1, in <module>
    from .. import parent
ValueError: Attempted relative import beyond toplevel package
Run Code Online (Sandbox Code Playgroud)

我使用的是Python 2.6.为什么会这样?如何使这个沙盒示例工作?

ebo*_*ebo 135

您正在从包"sub"导入.start.py即使有__init__.py礼物,它本身也不在包装中.

您需要从一个目录启动您的程序parent.py:

./start.py

./pkg/__init__.py
./pkg/parent.py
./pkg/sub/__init__.py
./pkg/sub/relative.py
Run Code Online (Sandbox Code Playgroud)

start.py:

import pkg.sub.relative
Run Code Online (Sandbox Code Playgroud)

现在pkg是顶级包,你的相对导入应该有效.


如果你想坚持你当前的布局,你可以使用import parent.因为您使用start.py启动解释器,所以start.py位于python路径中的目录.parent.py住在那里作为一个单独的模块.

__init__.py如果不将任何内容导入目录树中的脚本,也可以安全地删除顶级.

  • 不傻吗?所以在bash中,未能用".."来解决相对的上层目录会不会打扰你? (57认同)
  • 谢谢,但老实说这真的很傻.对于这样一个美丽的语言,我无法相信设计师会创造这样的限制.没有其他办法吗? (31认同)
  • 您混淆了"模块"和"包"这两个术语.'start.py'代表模块'start','mod'和'mod.sub'是包,'mod'是一个顶级包. (2认同)
  • 这根本不是愚蠢的.相对导入是指引用包中的兄弟模块的意思.如果要导入顶级模块,请使用绝对导入. (2认同)
  • 在我看来,python的想法是从启动父脚本的目录中使用“绝对”导入。因此,您可以使用绝对路径“导入父级”从同级导入父级模块。相对会导入某种遗产或其他东西。 (2认同)

Ami*_*ein 29

如果您要relative.py直接调用,即如果您确实要从顶级模块导入,则必须将其显式添加到sys.path列表中.
这是它应该如何工作:

# Add this line to the beginning of relative.py file
import sys
sys.path.append('..')

# Now you can do imports from one directory top cause it is in the sys.path
import parent

# And even like this:
from parent import Parent
Run Code Online (Sandbox Code Playgroud)

如果您认为上述情况可能导致某种不一致,您可以使用此代码:

sys.path.append(sys.path[0] + "/..")
Run Code Online (Sandbox Code Playgroud)

sys.path[0] 指的是从中运行入口点的路径.