超出相对导入中的顶级包错误

新手上路,请多包涵

似乎这里已经有很多关于 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 许可协议

阅读 911
1 个回答

编辑:在其他问题中对这个问题有更好/更连贯的答案:


为什么它不起作用? 这是因为 python 不记录包是从哪里加载的。 So when you do python -m test_A.test , it basically just discards the knowledge that test_A.test is actually stored in package (ie package 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不认为当前工作目录是一个包? _没有线索_,但天哪,它会很有用。

原文由 Multihunter 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题