我正在玩Python的导入系统,以便更好地了解它是如何工作的,我遇到了另一个问题。我有以下结构
pkg/
__init__.py
c.py
d.py
subpkg/
__init__.py
a.py
b.py
在a.py
内我有以下代码:
from . import b
from .. import d
在c.py
内,我有以下内容:
import subpkg.a
现在我收到以下错误:
ValueError:尝试相对导入超出顶级包
但为什么?我该如何解决?我从IDLE运行c.py
,pkg
应该被视为包,因为它有__init__.py
文件。
第一个导入工作正常,但是以下不起作用:
from .. import d
因为我试图从父包中导入某些东西,但显然我不能,出于某种奇怪的原因。
答案 0 :(得分:3)
Python 3更改了导入系统,因此每当您想要一个与您正在工作的模块相关的模块时,您需要相对导入(除非您弄乱PYTHON_PATH
或sys.path
)。
此处的正确用法应为
from .subpkg import a
当您使用IDLE时,您将拥有完全不同的环境。因此,您可以将当前位置添加到路径中,以便再次导入。
尝试:
sys.path.insert(0, '')
这可能很奇怪,但这是为了更好的
PS:如果这最后一件事不起作用 - 我现在没有IDLE环境 - 可能是因为工作目录设置错误。
答案 1 :(得分:3)
这让我质疑我的精神错乱。
问题源于人们误以为误以相对进口作为相对的路径。
相对导入取决于运行文件的位置。
此answer更深入地解释了python模块的实际工作方式,但仅作总结。
__main__
。pkg.subpkg.a
,则文件名中必须至少有2个点。 from ..
-3个点。现在是有趣的部分。
如果直接运行 c.py ,则其名称为from ...
,而 a.py 具有__main__
。
根据第二条语句,您必须在subpkg.a
的名称中至少有2个点才能在其中运行subpkg.a
。
修复
在 pkg 之外创建一个新文件,例如from ..
main.py
在main.py内部
pkg/
__init__.py
c.py
d.py
subpkg/
__init__.py
a.py
b.py
main.py
如果我们运行 main.py ,它的名称为import pkg.c
,而 a.py 的名称为__main__
。按照第二条语句,名称中现在有2个点,我们可以执行pkg.subpkg.a
还有一件事。现在 c.py 已作为模块加载,我们必须使用 from 加载 a.py 。
from ..
答案 2 :(得分:1)
我找到了这个解决方案:
#! /usr/bin/env python
import os
import sys
sys.path.append(os.path.realpath('.'))
from d import *
答案 3 :(得分:1)
只需在所有文件夹中添加/创建 init.py 文件即可解决问题。
文件夹 1 -文件夹2 -file1.py -文件夹3 -文件夹 4 - file2.py
我想使用 file2.py 中的 file1.py 中存在的方法 [基本上是两个级别]。 所以我在上面的所有文件夹和子文件夹中添加了空的 init.py,并在下面的 file2.py 中使用:-
从 folder2.file1 导入
答案 4 :(得分:0)
我对最佳答案表示感谢,但我发现提议的修复有点不令人满意。这是我的建议:只需将 sys.path.append(".") 添加到您的主文件中。这允许在不更改项目架构的情况下导入第一级包。只需删除之前不再需要的 .. 。