我在玩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
因为我试图从父包中导入一些东西,但显然我不能,出于某种奇怪的原因。
这让我质疑自己的疯狂。
问题源于人们的困惑错误地将相对导入视为路径相对,而事实并非如此。
相对导入取决于运行的文件的位置。
这个answer 更深入地解释了 python 模块的实际工作原理,但进行了总结。
__main__
。
pkg.subpkg.a
from ..
,文件名中必须至少有 2 个点。
from ...
- 3 点。
现在有趣的部分来了。
如果直接运行c.py,则它的名称为 __main__
,而a.py 的名称为
subpkg.a
。根据第二条语句,
subpkg.a
的名称中必须至少有 2 个点才能在其中运行
from ..
。
修复
在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,它会得到名称 __main__
,而a.py 会得到
pkg.subpkg.a
。根据第二条语句,它的名称现在有 2 个点,我们可以执行
from ..
还有一件事。现在
c.py已作为模块加载,我们必须使用from来加载a.py。
from .subpkg import a
PYTHONPATH
或
sys.path
)。这里正确的用法应该是
from .subpkg import a
当您使用 IDLE 时,您拥有一个完全不同的环境。因此,您可以将当前位置添加到您的路径中,以便导入再次工作。
尝试:
sys.path.insert(0, '')
这可能很奇怪,但这是为了更大的利益
PS:如果最后一件事不起作用 - 我现在没有 IDLE 环境 - 可能是因为工作目录设置错误。
尝试这个答案:
#! /usr/bin/env python
import os
import sys
sys.path.append(os.path.realpath('.'))
from d import *
__init__.py
文件即可解决问题。
file1.py
中
file2.py
中存在的方法[基本上是上两层]。所以我在上面的所有文件夹和子文件夹中添加了空的
__init__.py
,并在下面的
file2.py
中使用:
from folder2.file1 import <method_name>