微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python 3.9.5中的相对导入

如何解决python 3.9.5中的相对导入

我的文件夹结构如下

./fff
├── __init__.py
├── fg
│   ├── __init__.py
│   └── settings
│       ├── __init__.py
│       └── settings.py
└── obng
    └── test.py

我想把fg/settings里面的settings.py作为一个模块导入test.py

我已经添加了行

从 ..fg.settings 导入设置

但是当我运行它时,它给了我以下错误

回溯(最近一次调用最后一次): 文件“/mnt/d/Repos/fff/obng/test.py”,第 1 行,在 从 ..fg.settings 导入设置 导入错误:尝试在没有已知父包的情况下进行相对导入

根据 https://docs.python.org/3/reference/import.html#package-relative-imports

支持这种类型的相对导入

在这里做错了什么?

解决方法

通常,当您将 python 模块作为主模块(如 python filename.py)运行时,您不能使用相对导入,但可以使用 __package__ 来实现这一点。记住 __package__ 是 python 解析相对导入的方式:

1- 在您的根目录中创建一个名为 __init__.py 的文件 - fff。 (我可以看到你拥有它,我提到了完整性)

2- 将此代码放在您的 test.py 模块之上:

if __name__ == '__main__' and not __package__:
    import sys
    sys.path.insert(0,<path to parent directory of root directory - fff>)
    __package__ = 'fff.obng'

注意:sys.path 是 python 搜索模块以导入它们的地方。

3- 现在将您的相对导入语句放在上面的代码之后(在 if 语句中,因为我们不想在导入 test.py 时弄乱):

from ..fg.settings import settings

现在你可以叫你test.py,它会毫无问题地运行。我不建议使用这些技巧,但展示语言的灵活性并在某些情况下做你想做的事情是有益的。

其他好的解决方案:我认为绝对导入比这更简单、更干净。另外看看@Mr_and_Mrs_D 的回答,另一个好的解决方案是使用 -m 命令行标志运行您的模块。

,

这是你如何运行你的项目的问题——你应该从顶级包的父目录运行

$ cd ../fff
$ python -m fff.obng.test # note no py

然后将正确解析相对导入。这是一个直接从其文件夹运行脚本的反模式

,

相对导入基于当前模块的名称。运行时

python fff/obng/test.py

test.py 的名称将为 __main__,导入将不起作用。

在导入 fff.obng.test 的 fff 模块之外有另一个名为“test.py”的脚本会起作用

fff_top
├── fff
│   ├── fg
│   │   ├── __init__.py
│   │   └── settings
│   │       ├── __init__.py
│   │       └── settings.py
│   ├── __init__.py
│   └── obng
│       ├── __init__.py
│       └── test.py
└── test.py

使用 fff_top/test.py:

import fff.obng.test

然后,运行“外部”test.py 应该没问题:

python fft_top/test.py

或者,我建议完全放弃相对进口。一种方法是为您编写的每个包使用虚拟环境,例如使用 venv 库:

python -m venv venv

然后,在根文件夹中添加一个 setup.py 内容:

from setuptools import setup,find_packages
setup(name="fff",packages=find_packages())

并更改 obng/test.py 中的导入:

from fff.fg.settings import settings

最后,激活您的虚拟环境:

source venv/bin/activate

并以可编辑模式安装您的软件包:

pip install -e .

然后,在您完成上述所有步骤后:

python fff/obng/test.py

应该可以。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。