如何从python3中的同级目录导入?

时间:2019-03-06 01:52:42

标签: python-3.x python-import importerror siblings

我具有以下文件结构:

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.pyparse目录导入helpers,所以我这样做:

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

我从命令行运行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()

我发现了this postthis post,但是它们以一个文件结构很深的文件开头(我的名字在顶部)。我还发现了this post,但它似乎是在谈论一个软件包,而不是普通的.py。

这里有什么解决方案?

2 个答案:

答案 0 :(得分:1)

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

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

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

说明:

当您不使用实际安装的软件包,而只是导入相对于当前工作目录的内容时,该目录中的所有内容均被视为顶级软件包。在您的情况下,botpluginshelperscommands都是顶级程序包/模块。您当前的工作目录本身是不是软件包

所以当你做...

from ..helpers import parse

... helpers被认为是顶级程序包,因为它位于您当前的工作目录中,并且您试图从一个更高级别的目录( 当前的工作目录本身,而不是软件包。

这样做的时候...

from .helpers import parse

...您要相对于plugins进行导入。因此,.helpers解析为plugins.helpers

这样做的时候...

from helpers import parse

...由于它位于您当前的工作目录中,因此它发现helpers是顶级软件包。

答案 1 :(得分:0)

如果要从根目录执行代码,对此的最佳答案是使用os.getcwd()将根目录文件夹添加到Path中。 确保您的兄弟文件夹具有 init .py文件。

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

from sibling import module