似乎这里已经有很多关于 python 3 中的相对导入的问题,但是在经历了许多问题之后,我仍然没有找到我的问题的答案。所以这就是问题所在。
我有一个如下所示的包
package/
__init__.py
A/
__init__.py
foo.py
test_A/
__init__.py
test.py
我在 test.py 中有一行:
from ..A import foo
现在,我在 package
的文件夹中,我运行
python -m test_A.test
我收到消息
"ValueError: attempted relative import beyond top-level package"
但是如果我在 package
的父文件夹中,例如,我运行:
cd ..
python -m package.test_A.test
一切都很好。
现在我的问题是: 当我在 package
的文件夹中时,我将 test_A 子包中的模块运行为 test_A.test
,根据我的理解, ..A
只上升一级,仍然在 package
文件夹中,为什么它会给出消息说 beyond top-level package
。导致此错误消息的确切原因是什么?
原文由 shelper 发布,翻译遵循 CC BY-SA 4.0 许可协议
编辑:在其他问题中对这个问题有更好/更连贯的答案:
为什么它不起作用? 这是因为 python 不记录包是从哪里加载的。 So when you do
python -m test_A.test
, it basically just discards the knowledge thattest_A.test
is actually stored inpackage
(iepackage
is not considered a包裹)。尝试from ..A import foo
正在尝试访问它不再拥有的信息(即加载位置的同级目录)。它在概念上类似于在from ..os import path
math
。这会很糟糕,因为您希望包是不同的。如果他们需要使用另一个包中的东西,那么他们应该使用from os import path
全局引用它们,并让 python 计算出它所在的位置$PATH
和$PYTHONPATH
当您使用
python -m package.test_A.test
时,然后使用from ..A import foo
解决得很好,因为它会跟踪package
中的内容 只是访问子目录的位置,并且您正在.为什么python不认为当前工作目录是一个包? _没有线索_,但天哪,它会很有用。