nbr*_*bro 33 python-import python-3.x
我正在玩Python的导入系统,以便更好地理解它是如何工作的,我遇到了另一个问题.我有以下结构
pkg/
__init__.py
c.py
d.py
subpkg/
__init__.py
a.py
b.py
Run Code Online (Sandbox Code Playgroud)
在里面a.py我有以下代码:
from . import b
from .. import d
Run Code Online (Sandbox Code Playgroud)
在里面c.py我有以下内容:
import subpkg.a
Run Code Online (Sandbox Code Playgroud)
现在我收到以下错误:
ValueError:尝试相对导入超出顶级包
但为什么呢?我该如何解决?我c.py从IDLE 运行,pkg应该被认为是一个包,因为它有__init__.py文件.
第一个导入工作正常,但它是以下不起作用:
from .. import d
Run Code Online (Sandbox Code Playgroud)
因为我试图从父包中导入一些东西,但显然我不能,因为一些奇怪的原因.
typ*_*n04 37
这让我怀疑我的精神错乱。
问题源于人们错误地将相对导入视为路径相对而不是路径相对的混淆。
相对导入取决于运行的文件的位置。
这个答案更深入地解释了 python 模块的实际工作方式,但要总结一下。
__main__.pkg.subpkg.afrom ..,文件名中必须至少有 2 个点。from ...- 3 点。现在是有趣的部分。
如果您直接运行c.py,那么它会被赋予名称,__main__而a.py具有subpkg.a.
根据第二条语句,您必须在名称中至少有 2 个点subpkg.a才能from ..在其中运行。
修复
在pkg之外创建一个新文件,比如main.py
pkg/
__init__.py
c.py
d.py
subpkg/
__init__.py
a.py
b.py
main.py
Run Code Online (Sandbox Code Playgroud)
在 main.py 里面
import pkg.c
Run Code Online (Sandbox Code Playgroud)
如果我们运行main.py,它会得到 name __main__,而a.py会得到pkg.subpkg.a. 根据第 2 条语句,它现在在名称中有 2 个点,我们可以执行from ..
还有一件事。现在c.py已作为模块加载,我们必须使用from加载a.py。
from .subpkg import a
Run Code Online (Sandbox Code Playgroud)
Python 3 更改了导入系统,因此每次您想要一个与您正在工作的模块相邻的模块时,您都需要相对导入(除非您弄乱了PYTHONPATH或sys.path)。
这里的正确用法应该是
from .subpkg import a
Run Code Online (Sandbox Code Playgroud)
当您使用 IDLE 时,您将拥有一个完全不同的环境。因此,您可以将当前位置添加到您的路径中,以便导入再次工作。
尝试:
sys.path.insert(0, '')
Run Code Online (Sandbox Code Playgroud)
这可能很奇怪,但这是为了更大的利益
PS:如果最后一件事不起作用——我现在没有空闲环境——可能是因为工作目录设置错误。
试试这个答案:https : //stackoverflow.com/a/17361545/754991
| 归档时间: |
|
| 查看次数: |
25350 次 |
| 最近记录: |