繁体   English   中英

Python + 子模块:ImportError:尝试在没有已知父 package 的情况下进行相对导入

[英]Python + Submodules: ImportError: attempted relative import with no known parent package

我一直在为 python 上的相对导入而苦苦挣扎。

我的项目结构如下所示:

root_dir
├── main.py
├── Pipfile
├── Pipfile.lock
├── unit_tests
│   ├── __init__.py
│   ├── test_first.py
│   └── test_second.py
└── my_package
    ├── __init__.py
    ├── first.py
    ├── second.py
    └── third.py

我想将位于my_package中的文件中的一组函数导入test_first.py

根据官方文档,语法应该如下:

from ..my_package import first

当我这样做时,我得到以下异常:

Traceback (most recent call last):
  File "/home/user/dev/root_dir/my_package/unit_tests/first.py", line 8, in <module>
    from ..my_package import first
ImportError: attempted relative import with no known parent package

我还尝试使用以下语法导入文件:

from root_dir.my_package import first

当我这样做时,我得到以下异常:

ModuleNotFoundError: No module named 'root_dir'

值得一提的是,我正在使用pipenv来处理虚拟环境。 知道为什么会这样吗?

谢谢。

首先,我将为您提供对我有用的代码。 然后,我将做一个简短的解释。 这是一个简短的 function 应该让您从根目录导入。

解决方案

import os, sys

def access_root_dir(depth = 1):
    current_dir = os.path.dirname(os.path.realpath(__file__))
    parent_dir = os.path.dirname(current_dir)
    args: list = [parent_dir]
    for _ in range(depth):
        args.append('..')
    
    rel_path = os.path.join(*args)
    sys.path.append(rel_path) 

# At the top of test_first.py
access_root_dir(2)
import root_dir   

由于根目录是test_first.py的祖父母,因此您需要 go 到深度 2:

解释

我在我的一个项目中遇到了同样的问题,并发现通过更改sys.path修复了从父目录导入的问题。 除非所有内容都是 package 的一部分,否则使用sys.path.append(abs_path_to_root)之类的东西将绝对路径附加到根目录似乎不起作用。 Python 默认不会访问导入中的父目录。

# Case 1: Relative path to parent - works
current_dir = os.path.dirname(os.path.realpath(__file__))
relative_path = os.path.join(current_dir, '..')
sys.path.append(relative_path)
import parent_module_name # This works for me (Python 3.9)

# Case 2: Absolute path to parent - Doesn't work 
current_dir = os.path.dirname(os.path.realpath(__file__))
parent_dir = os.path.dirname(current_dir)
sys.path.append(parent_dir)
import parent_module_name # raises ModuleNotFoundError

我认为你需要做“...my_package”。 使用三个“...”

“..”暗示父根目录。 最后 ”。” 正在访问子文件夹 my_package。

当前工作目录不是 package 使用os.getcwd()查看它是什么,但它很可能是root_dir

在这种情况下,您可以直接按名称导入顶级包,而无需相对导入; 您应该直接从my_package导入,如下所示:

from my_package import first

...或者:

from my_package.first import do_something

复制的文件树:

root_dir
├── main.py
├── my_package
│   ├── __init__.py
│   └── first.py
└── unit_tests
    ├── __init__.py
    └── test_first.py

main.py的内容:

from unit_tests import test_first

if __name__ == "__main__":
    test_first.test_something()

如果您尝试进行相对导入,即: from..my_package import first你会得到:

ImportError: attempted relative import beyond top-level package

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM