python 3.9.5中的相对导入

2024-10-02 16:30:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我的文件夹结构如下

./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导入设置 ImportError:尝试在没有已知父包的情况下进行相对导入

根据https://docs.python.org/3/reference/import.html#package-relative-imports支持这种类型的相对导入

我做错了什么


Tags: 模块文件pytest文件夹settingsfffinit
3条回答

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

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

应该有用

通常,当您将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的答案,另一个好的解决方案是使用^{}命令行标志运行模块

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

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

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

相关问题 更多 >