python 3.9.5 中的相对导入

Sha*_*ash 4 python import relative-import

我的文件夹结构如下

\n
./fff\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 fg\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 settings\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 settings.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 obng\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test.py\n
Run Code Online (Sandbox Code Playgroud)\n

我想将 fg/settings 中的 settings.py 作为模块导入到 test.py 中

\n

我已经添加了该行

\n

从 ..fg.settings 导入设置

\n

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

\n

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

\n

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

\n

我在这里做错了什么?

\n

Mr_*_*s_D 7

这取决于您如何运行项目 - 您应该从顶级包的父目录运行,如下所示

$ cd ../fff
$ python -m fff.obng.test # note no py
Run Code Online (Sandbox Code Playgroud)

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


Sor*_*ary 6

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

__init__.py1-在根目录中创建一个名为 - 的文件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'
Run Code Online (Sandbox Code Playgroud)

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

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

from ..fg.settings import settings
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我是这个答案的忠实粉丝,请继续为 `sys.path` hack 提供建议! (4认同)
  • 请停止建议使用“sys.path”黑客 (2认同)