Python 无系统或操作系统的相对导入校正
我已经阅读了几乎所有修复相对进口的解决方案,但似乎没有一个有效。以下是我目前的结构:Python 无系统或操作系统的相对导入校正,python,python-3.x,Python,Python 3.x,我已经阅读了几乎所有修复相对进口的解决方案,但似乎没有一个有效。以下是我目前的结构: structures \ containers \ queue.py \ trees \ binaryTree.py 我想将队列导入到我的二叉树文件中,但我遇到了相对导入问题。我尝试了\uuuu init\uuuuu.py,但这似乎无法解决相对导入问题。有解决办法吗?(我使用的是Python 3.3.x) 编辑: 这是我的进口声明 from .containers.queue import Queue
structures
\ containers
\ queue.py
\ trees
\ binaryTree.py
我想将队列导入到我的二叉树文件中,但我遇到了相对导入问题。我尝试了\uuuu init\uuuuu.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
回溯(最近一次呼叫最后一次):
文件“binaryTree.py”,第1行,在
from.containers.queue导入队列
SystemError:未加载父模块“”,无法执行相对导入
以脚本形式运行包模块是一种“有趣”的体验。默认情况下,脚本不是包的一部分,并且对相对导入一无所知。假设脚本在已安装的环境中运行,并且使用绝对导入<代码>distutils例如,在安装软件包时,将它们放在不同的目录中
如果脚本隐藏在包发行版中,它可以通过将其包目录的父目录添加到sys.path
并执行绝对导入来欺骗系统。这是危险的,因为现在所有与包dir对等的目录都是潜在的python模块
定义在脚本中执行相对导入的方法:
当主模块由其文件名指定时,包属性将设置为无。为了在直接执行模块时允许相对导入,在第一个相对导入语句之前需要类似于以下内容的样板文件:
如果name==“main”和package为无:
包=“应为.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会认为它是一个与脚本不同的模块,因此所有内容(包括副作用)都是重复的。您能举一个代码示例说明如何导入吗,以及您收到的错误消息?@RamiroBerrelleza在导入语句中添加并出错。您是作为脚本运行binaryTree.py
,还是从其他地方导入它?如果是脚本,则适用不同的规则@tdelaney我将它作为测试脚本运行,我可能会将测试文件放在更高的位置,以便导入工作…不幸的是,同样的问题。。。这可能是我无法解决的问题,因为Python已经决定了相对导入是魔鬼…在所有三个目录中(结构/\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuupy
,结构/容器/\uuuuuuu init\uuuuuuuuuuuuuuuuuuuuupy
)和结构/树/\uuuuuuuuuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。你有structures/\uuuuu init\uuuuuuuuupy
,structures/containers/\uuuuuu init\uuuuuuuuupy
和structures/tree/\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?您是否在结构
(或其在python路径中)的父目录中?@tdelaney我在结构/树
中,我将尝试在这个目录以及我还没有尝试过的另一个位置添加一个\uuuu init\uuuuuuuy.py
文件。根据原理,我将标记为正确,但我认为这是一件令人沮丧的事情。我知道相对导入是不安全的,指针也是不安全的,C++仍然允许这些。相对的导入对于包模块是安全的。挑战在于,当模块作为脚本运行时,它不再在包中。“不安全”部分仅在顶级软件包不可导入且您必须摆弄sys.path
时才需要。在这里,您可能会遇到这样的风险:对等目录被视为模块,而它们本不应该被视为模块。对,我理解脚本与模块的原理,但感觉就像是解释器在哄我,让我避免一些破坏性的东西。。。Python的PARM课程,我想,偶尔从抽象的格子太多抽象。
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