关于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子包中的模块时,根据我的理解,..A
只上升一个级别,它仍然在package
文件夹中,为什么它会给出消息说beyond top-level package
。导致此错误消息的确切原因是什么?
试试这个。 为我工作。
编辑:这个问题在其他问题上有更好/更连贯的答案:
为什么不起作用?这是因为python不记录从何处加载包。所以当你做
python -m test_A.test
的时候,它基本上只是抛弃了test_A.test
实际上存储在package
中的知识(即package
不被视为包)。尝试from ..A import foo
是试图访问它不再具有的信息(即加载位置的同级目录)。这在概念上类似于在math
中的文件中允许from ..os import path
。这会很糟糕,因为您希望包是不同的。如果他们需要使用另一个包中的某些内容,那么他们应该使用from os import path
全局引用它们,并让python计算出$PATH
和$PYTHONPATH
的位置。当您使用
python -m package.test_A.test
时,使用from ..A import foo
解析很好,因为它跟踪package
中的内容,并且您只访问加载位置的子目录。为什么python不将当前工作目录视为一个包?没有线索,但天哪,这很有用。
假设:
如果您在
package
目录中,A
和test_A
是单独的包。结论:
..A
只允许在包内导入。进一步说明:
如果希望强制将包放置在
sys.path
上的任何路径上,则使相对导入仅在包中可用是很有用的。编辑:
当前工作目录通常位于sys.path中。所以,那里的所有文件都是可导入的。这是自Python 2以来的行为,当时还不存在包。将运行目录设置为包将允许将模块导入为“import.a”和“import a”,这将是两个不同的模块。也许这是一个不一致的考虑。
相关问题 更多 >
编程相关推荐