Python 还有一个ImportError:尝试在没有已知父包的情况下进行相对导入

Python 还有一个ImportError:尝试在没有已知父包的情况下进行相对导入,python,import,package,python-import,Python,Import,Package,Python Import,我有以下目录结构: py_test ├── __init__.py ├── dir1 │ ├── __init__.py │ └── script1.py └── dir2 ├── __init__.py └── script2.py 在script2中,我想“导入..\script1” 我在script2中尝试的内容: 不起作用 from ..dir1 import script1 ImportError: attempted relative import with

我有以下目录结构:

py_test
├── __init__.py
├── dir1
│   ├── __init__.py
│   └── script1.py
└── dir2
    ├── __init__.py
    └── script2.py
script2
中,我想“
导入..\script1

我在
script2
中尝试的内容:

  • 不起作用

    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,最简单(即文件最少)的file/dir结构是什么使它工作的? 我知道,但我想知道是否可以避免创建该目录结构,并且仍然使用type-1
    import

    我目前正在使用,它使用type-2
    import

    相关的:


    如评论中所述,如果您的入口点是
    script2.py
    ,则尝试将模块导入目录将不起作用

    如中所述:

    如果模块的
    \uuuu name\uuuuu
    不包含任何包信息(例如,它被设置为
    \uuuuu main\uuuuu
    ),则无论模块实际位于文件系统上的何处,都会将相对导入解析为模块是顶级模块

    如果模块的
    \uuuu name\uuuuu
    是入口点,或者是用类似于
    python script2.py
    的东西传递给解释器的入口点,则将其设置为
    \uuuuuu main\uuuuuu

    任何这样运行的python模块不再具有从更高目录导入文件所需的信息

    因此,您有两种选择:

    选项1:继续使用带有
    sys.path.append的变通方法
    这将按照您希望的方式工作,但相当麻烦

    选项2:让你的切入点位于顶层
    假设您的包有多个需要运行的脚本,您可以创建一个新文件,导入
    script1
    script2
    ,然后根据命令行参数调用所需的功能。然后,您将能够保持当前的目录结构,并使您的相对导入工作正常,而无需对sys.path

    进行任何修改。您是如何运行代码的?从哪个工作目录?@mkrieger1-从Jupyter笔记本中的
    dir2
    。您不能导入相对高于主脚本位置的内容(我假定为“script2.py”)。在“py_test”中放置一个主脚本,然后可以导入并运行“script2.py”。当通过导入
    py_test
    包的任何模块运行时,它将正常运行。导入包是这样组织的,可以作为要使用的包导入。因此,从内部执行多个入口点是没有意义的,通常它们永远不会(一起)工作。