python 3.9.5中的相对导入

cgyqldqp  于 2021-08-25  发布在  Java
关注(0)|答案(3)|浏览(398)

我的文件夹结构如下

./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行,from..fg.settings导入设置导入错误:尝试在没有已知父包的情况下进行相对导入
根据,支持此相对导入样式https://docs.python.org/3/reference/import.html#package-相对进口
我做错了什么?

mwngjboj

mwngjboj1#

通常,当您像主模块一样运行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 命令行标志。

0yg35tkg

0yg35tkg2#

相对导入基于当前模块的名称。跑步时

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

然后,运行“external”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

应该有用。

ecr0jaav

ecr0jaav3#

这是一个如何运行项目的问题——应该从顶级包的父目录运行,如中所示

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

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

相关问题