没有sys或os的相对导入修正

时间:2015-04-16 22:37:55

标签: python python-3.x

我已经阅读了几乎所有用于修复相对导入的解决方案,但这些解决方案似乎都不起作用。这是我目前的结构:

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

2 个答案:

答案 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