我具有以下文件结构:
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.py
从parse
目录导入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 post和this post,但是它们以一个文件结构很深的文件开头(我的名字在顶部)。我还发现了this post,但它似乎是在谈论一个软件包,而不是普通的.py。
这里有什么解决方案?
答案 0 :(得分:1)
您可以删除点,它应该可以工作:
# parsemessages.py
from helpers import parse
parse.execute("string to be parsed")
如果您真的不想将其打包,这可能是最好的解决方案。您还可以将整个项目嵌套到更深的一个目录,并像python3 foo/bot.py
那样命名。
说明:
当您不使用实际安装的软件包,而只是导入相对于当前工作目录的内容时,该目录中的所有内容均被视为顶级软件包。在您的情况下,bot
,plugins
,helpers
和commands
都是顶级程序包/模块。您当前的工作目录本身是不是软件包。
所以当你做...
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