如何从 python3 中的兄弟目录导入?

How to import from a sibling directory in python3?

我有以下文件结构:

bot
├── LICENSE.md
├── README.md
├── bot.py # <-- file that is executed from command line
├── plugins
│   ├── __init__.py
│   ├── debug.py
│   └── parsemessages.py
├── helpers
│   ├── __init__.py
│   ├── parse.py
│   └── greetings.py
└── commands
    ├── __init__.py
    └── search.py

bot.py,当从命令行执行时,将加载 plugins 目录中的所有内容。

我希望 plugins/parsemessages.pyhelpers 目录导入 parse,所以我这样做了:

# parsemessages.py
from ..helpers import parse
parse.execute("string to be parsed")

I 运行 python3 bot.py 来自命令行。

我收到以下错误:

File "/home/bot/plugins/parsemessages.py", line 2, in <module>
  from ..helpers import parse
ValueError: attempted relative import beyond top-level package

所以我把两个点变成一个:

# parsemessages.py
from .helpers import parse
parse.execute("string to be parsed")

...但我收到另一个错误:

File "/home/bot/plugins/parsemessages.py", line 2, in <module>
  from .helpers import parse
ImportError: No module named 'plugins.helpers'

我怎样才能让这个导入工作?

需要说明的是,我这里并不是要打包,这只是一个普通的脚本。话虽这么说,我不愿意乱用 sys.path - 我希望它干净易用。

此外,我希望将 parse 导入为 parse - 因此对于上面的示例,我应该输入 parse.execute() 而不是 execute().

我找到了 and this post, but they start with a file that's quite deep in the file structure (mine is right at the top). I also found this post,但它似乎在谈论一个包而不是一个普通的 .py。

这里的解决方案是什么?

您可以删除这些点,它应该可以工作:

# parsemessages.py
from helpers import parse
parse.execute("string to be parsed")

如果您真的不想将其打包,那可能是您的最佳解决方案。您还可以将整个项目嵌套到更深的一个目录,并将其命名为 python3 foo/bot.py.

解释:

当您不使用实际安装的包而只是导入与当前工作目录相关的内容时,该目录中的所有内容都被视为顶级包。在您的例子中,botpluginshelperscommands 都是顶级 packages/modules。您当前的工作目录本身不是一个包

所以当你做...

from ..helpers import parse

... helpers 被认为是顶级包,因为它在您当前的工作目录中,并且您正试图从比它更高的级别导入 (from 你当前的工作目录本身,它不是一个包。

当你做...

from .helpers import parse

...您正在导入相对于 plugins。所以 .helpers 解析为 plugins.helpers.

当你做...

from helpers import parse

...它发现 helpers 是顶级包,因为它在您当前的工作目录中。

如果您想从根目录执行代码,我对此的最佳回答是使用 os.getcwd() 添加到您的根文件夹的路径。 确保你的兄弟文件夹有一个 init.py 文件。

import os
os.sys.path.insert(0, os.getcwd())

from sibling import module