我已经阅读了几乎所有用于修复相对导入的解决方案,但这些解决方案似乎都不起作用。这是我目前的结构:
structures
\ containers
\ queue.py
\ trees
\ binaryTree.py
我想将队列导入到我的二进制树文件中,但是我遇到了相对导入问题。我试过__init__.py
,但这似乎无法解决相对导入问题。这个问题有方法解决吗? (我在Python 3.3.x上)
编辑:
这是我的导入声明
from .containers.queue import Queue
和错误:
Traceback (most recent call last):
File "binaryTree.py", line 1, in <module>
from .containers.queue import Queue
SystemError: Parent module '' not loaded, cannot perform relative import
答案 0 :(得分:2)
将包模块作为脚本运行是一种“有趣”的体验。默认情况下,脚本不是包的一部分,并且不了解相关导入的任何信息。假设脚本在已安装的环境中运行,并且它使用绝对导入。例如,distutils
在安装软件包时将它们放在不同的目录中。
如果您的脚本隐藏在您的软件包发行版中,它可以通过将其软件包目录的父目录添加到sys.path
并进行绝对导入来欺骗系统。这很危险,因为现在所有与包dir对等的目录都是潜在的python模块。
pep 366定义了在脚本中执行相对导入的方法:
当主模块由其文件名指定时,包属性将设置为无。要在直接执行模块时允许相对导入,在第一个相对导入语句之前需要类似于以下的样板:
如果名称 ==“主要”且包为无: 包 =“expected.package.name”
请注意,只有顶层包可以通过sys.path访问时,此样板才足够。需要操作sys.path的其他代码才能使直接执行工作,而顶层包不能被导入。
但在我看来它仍然很尴尬。希望有人有一个更清洁的方法来做到这一点,但这是我认为你需要的:
if __name__ == "__main__" and __package__ is None:
# name package for relative imports
__package__ = "structures.trees"
# add package dir to python path
import os
import sys
pkg_parent = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
sys.path.insert(0, pkg_parent)
# ...and import
import structures.trees
from ..containers.queue import Queue
但你仍然有问题。如果你的包导入binaryTree
,python认为它与你的脚本不同,所以所有东西(包括副作用)都是重复的。
答案 1 :(得分:1)
from ..containers.queue import Queue