Python 3.x ValueError:尝试在顶级包之外进行相对导入
为了更好地理解Python的导入系统是如何工作的,我在玩Python的导入系统时遇到了另一个问题。我有以下结构Python 3.x ValueError:尝试在顶级包之外进行相对导入,python-3.x,python-import,Python 3.x,Python Import,为了更好地理解Python的导入系统是如何工作的,我在玩Python的导入系统时遇到了另一个问题。我有以下结构 pkg/ __init__.py c.py d.py subpkg/ __init__.py a.py b.py 在a.py内a.py我有以下代码: from . import b from .. import d 在c.py中,我有以下内容: import subpkg.a 现在我收到以下错误:
pkg/
__init__.py
c.py
d.py
subpkg/
__init__.py
a.py
b.py
在a.py内a.py
我有以下代码:
from . import b
from .. import d
在c.py
中,我有以下内容:
import subpkg.a
现在我收到以下错误:
ValueError:尝试在顶级包之外进行相对导入
但是为什么呢?我怎样才能解决它?我正在空闲状态下运行c.py
,而pkg
应该被视为一个包,因为它有\uuuuu init\uuuuuuu.py
文件
第一次导入工作正常,但以下内容不起作用:
from .. import d
因为我正试图从父包导入一些东西,但由于某些奇怪的原因,显然我无法导入。Python 3更改了导入系统,因此每当您想要一个与您正在工作的模块相关的模块时,您都需要相对导入(除非您弄乱了
PYTHONPATH
或sys.path
)
这里的正确用法应该是
from .subpkg import a
当您使用IDLE时,您的环境完全不同。因此,可以将当前位置添加到路径中,以便导入再次工作
尝试:
这可能很奇怪,但这是为了更大的利益
PS:如果最后一件事不起作用——我现在没有空闲的环境——可能是因为工作目录设置错误
试试这个答案:这让我怀疑我的精神错乱 问题源于人们错误地将相对导入视为路径相对,而不是路径相对 相对导入取决于运行的文件的位置。 本文将更深入地解释python模块实际上是如何工作的,但仅作总结
- 如果它作为顶级脚本加载(直接运行),则其名称为
\uuuuu main\uuuu
- 如果它是作为模块加载的(带有导入),则其名称为文件名,前面是它所属的任何包/子包的名称,以点分隔-
pkg.subpkg.a
,文件名中必须至少有2个点<代码>来自…
-3点\uuu main\uu
,而a.py具有子kg.a
根据第2条语句,您必须在subkg.a
名称中至少有2个点才能从..中运行
修复程序
在pkg之外创建一个新文件,比如main.py
pkg/
__init__.py
c.py
d.py
subpkg/
__init__.py
a.py
b.py
main.py
内main.py
import pkg.c
如果我们运行main.py,它的名称是\uuu main\uuu
,而a.py get的名称是pkg.subpkg.a
。根据第2条语句,它的名称中现在有2个点,我们可以从..
还有一件事。既然c.py是作为模块加载的,那么我们必须使用from来加载a.py
我找到了这个解决方案:
#/usr/bin/env python
导入操作系统
导入系统
sys.path.append(os.path.realpath('.'))
从d进口*
我很感谢上面的答案,但我觉得建议的解决方案有点不令人满意。我的建议是:只需将sys.path.append(“.”)添加到主文件中。这允许导入第一级包,而无需对项目架构进行任何更改。放下前一个。。不再需要了。只需在所有文件夹中添加/创建init.py文件即可解决问题
折叠1
-折叠2
-file1.py
-折页3
-折页4
-file2.py
我想在file2.py中使用file1.py中的一个方法[基本上是向上两级]。
因此,我在上面的所有文件夹和子文件夹中添加了空的init.py,并在下面的file2.py中使用:-
从folder2.file1导入如果我从.subpkg导入a接收:
系统错误:未加载父模块“”,无法从空闲模块和终端执行相对导入
。@nbro这是因为您在空闲模块内,但当您在模块内运行时,导入应该是这样的。IDLE是一个糟糕的IDE,对python开发总体上是不利的。在空闲模块和内部模块上最有效的选项是使用完整的包名:from pkg import subpkg.a
在sys.path
上添加pkg
的目录后,“在模块内运行它”是什么意思?我说过,我按照您的建议从终端和空闲运行文件c.py
(作为main),它给出了我上面提到的错误。IDLE是一个糟糕的IDE,但它是Python自带的吗?携带一个可怕的IDE的目的是什么?你可以说IDLE是一个过于简单的IDE,当然它不是最好的IDE之一,但理论上它应该可以很好地与Python配合使用,否则就没有什么意义了。我已经对你所说的内容和Python的导入系统做了一些介绍,我想我对它的工作原理有了更多的了解。基本上,作为“主”文件运行的文件与作为其他模块或“主”文件导入的模块或包运行的文件是有区别的。如果只有一个文件运行整个应用程序,则可以在子模块和子包之间进行相对导入。另一方面,正如您所说,相对导入在作为“main”运行的文件中不起作用。不幸的是,这是一个错误的限制…from.import a
无法回答问题。问题是如何从。。导入d。
import pkg.c
from .subpkg import a