python - Python + 子模块:ImportError:尝试使用没有已知父包的相对导入
问题描述
我一直在为 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
来处理虚拟环境。知道为什么会这样吗?
谢谢。
解决方案
首先,我将为您提供对我有用的代码。然后,我将做一个简短的解释。这是一个简短的函数,可以让您从根目录导入。
解决方案
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
,因此您需要进入深度 2:
解释
我在我的一个项目中遇到了同样的问题,并发现从父目录导入已通过更改sys.path
. 除非一切都是包的一部分,否则使用类似的东西将绝对路径附加到根目录
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
推荐阅读
- php - 如何在 PHP 中使用 Select 选项从数据库中获取数据?
- linux - 在linux终端中复制和粘贴
- angular - 如何自定义垫子分页器
- email - Laravel:我如何从 Localhost Mailgun 发送电子邮件
- java - 使用 EnvelopedSignature.open 时出错(错误消息:“输出密码启动失败”)
- java - 反应堆 switchIfEmpty 和验证执行
- node.js - 使用 csvtojson 时,“字符串”类型的参数不可分配给“可读”类型的参数
- go - 如何理解 core/types/block.go 中的 'rlpHash' 方法
- angular - 更新到角度/材料 v-6.4.7 给我错误
- r - 在 R 中创建具有缺失日期值和格式的多个变量