又一个 ImportError: 尝试使用未知父包进行相对导入

15

我有以下的目录结构:

py_test
├── __init__.py
├── dir1
│   ├── __init__.py
│   └── script1.py
└── dir2
    ├── __init__.py
    └── script2.py

script2中,我想要“import ..\script1”。

我尝试过的方法:

  1. 无效

from ..dir1 import script1
ImportError: attempted relative import with no known parent package`
  • 作品

    import sys, os
    path2add = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, 'dir1')))
    if (not (path2add in sys.path)) :
        sys.path.append(path2add)
    
  • 如果我想选择选项1,最简单的文件/目录结构是什么(即使用最少的文件)使其工作? 我知道这个,但我想知道是否可以避免创建那个目录结构,仍然可以使用类型1的import

    我目前正在使用此解决方法,它使用类型2的import

    相关:

    如何导入位于上级目录中的Python类?

    从一个级别更高的目录(包)导入模块

    运行Python解释器时出现“ImportError:尝试相对导入而没有已知的父包”

    使用importlib动态导入包含相对导入的模块

    如何在不同的Python文件中导入变量


    你是从哪个工作目录运行代码的? - mkrieger1
    @mkrieger1 - 在Jupyter笔记本中的“dir2”文件夹内。 - sancho.s ReinstateMonicaCellio
    3
    你无法在主脚本的位置之上相对导入(我假设你有一个名为“script2.py”的脚本)。请在“py_test”文件夹中放置一个主脚本,从而可以导入并运行“script2.py”。 - Michael Butscher
    只要从导入你的“py_test”包的任何模块中运行,它就能正常运行。 - progmatico
    1
    一个导入包被组织成这样,以作为一个要使用的包进行导入。因此,在内部拥有多个执行入口点是没有意义的,并且通常它们永远不会一起工作。 - progmatico
    1个回答

    4
    如评论中所述,如果您的入口点是 script2.py ,则尝试导入上一级目录的模块将无法正常工作。
    如您提供的链接所述:
    如果模块的__name__不包含任何包信息(例如设置为__main__),则相对导入将被解析为顶级模块,而不考虑模块实际位于文件系统上的位置。
    如果它是入口点或者您使用类似python script2.py这样的方式将其传递给解释器,则模块的__name__将设置为__main__
    以这种方式运行的任何Python模块都不再具有从较高目录导入文件所需的信息。
    因此,您有两个选择:
    选项1:继续使用sys.path.append的解决方法。
    这将按您希望的方式工作,但相当繁琐。
    选项2:将入口点制作为顶级。
    假设您的软件包有多个需要运行的脚本,您可以创建一个新文件,在其中导入script1script2,然后根据命令行参数调用所需的功能。然后,您将能够保留当前的目录结构,并让相对导入正常工作,而无需使用sys.path进行任何调整。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接