我试着通读关于兄弟姐妹导入的问题,甚至 软件包文档,但我还没找到答案。

结构如下:

├── LICENSE.md
├── README.md
├── api
│   ├── __init__.py
│   ├── api.py
│   └── api_key.py
├── examples
│   ├── __init__.py
│   ├── example_one.py
│   └── example_two.py
└── tests
│   ├── __init__.py
│   └── test_one.py

示例和测试目录中的脚本如何从 API模块和从命令行运行?

另外,我希望避免对每个文件都使用难看的sys.path.insert。肯定 这可以在Python中完成,对吧?


当前回答

对于2021年的读者:如果你对pip没有信心,请安装-e:

考虑一下这个层次结构,正如Python 3中相对导入的答案所推荐的那样:

MyProject
├── src
│   ├── bot
│   │   ├── __init__.py
│   │   ├── main.py
│   │   └── sib1.py
│   └── mod
│       ├── __init__.py
│       └── module1.py
└── main.py

main.py的内容,这是起点,我们在这里使用绝对导入(没有前导点):

from src.bot import main


if __name__ == '__main__':
    main.magic_tricks()

bot/main.py的内容,它利用了显式的相对导入:

from .sib1 import my_drink                # Both are explicit-relative-imports.
from ..mod.module1 import relative_magic

def magic_tricks():
    # Using sub-magic
    relative_magic(in=["newbie", "pain"], advice="cheer_up")
    
    my_drink()
    # Do your work
    ...

原因如下:

当执行python MyProject/main.py时,/到/MyProject的路径被添加到sys.path中。 绝对导入import src。机器人会读的。 从…mod部分意味着它将上升一级到MyProject/src。 我们能看看吗?是的,因为路径/to/MyProject被添加到sys.path中。

所以重点是:

我们应该把主脚本放在MyProject/src旁边,因为当做相对引用时,我们不会离开src,绝对导入导入src。为我们提供合适的作用域:src/ scope。

参见:ModuleNotFoundError:没有名为“sib1”的模块

其他回答

为了防止在Eclipse上使用Pydev的人在这里结束:您可以使用Project->Properties将兄弟的父路径(以及调用模块的父路径)添加为外部库文件夹,并在左侧菜单Pydev- pythonpath下设置外部库。然后你可以从你的兄弟导入,例如from sibling import some_class。

项目

1.1用户

1.1.1 about.py

1.1.2 init.py

1.2技术

1.2.1 info.py

1.1.2 init.py

现在,如果你想访问User包中的about.py模块,从Tech包中的info.py模块,那么你必须将cmd(在windows中)路径带到项目中,即。 **C:\Users\Personal\Desktop\Project>**根据上面的包示例。你必须从这个路径输入python -m Package_name.module_name 例如,对于上面的包,我们必须做,

c:\用户\个人\桌面\项目>python -m Tech.info

小鬼点

不要在info模块后使用.py扩展名,即python -m Tech.info.py 输入this,其中兄弟包位于同一级别。 -m是标志,要检查它,你可以从CMD python——help

我想评论一下np8提供的解决方案,但我没有足够的声誉,所以我只想说,你可以完全按照他们建议的那样创建一个setup.py文件,然后执行pipenv install——dev -e。将其转换为可编辑的依赖项。然后你的绝对导入将工作,例如从api。API import foo,你就不必在系统范围的安装上瞎折腾了。

文档

您需要查看import语句是如何在相关代码中编写的。如果examples/example_one.py使用以下import语句:

import api.api

...然后,它期望项目的根目录位于系统路径中。

不需要任何hack(如你所说)就能支持它的最简单的方法就是从顶级目录运行这些例子,就像这样:

PYTHONPATH=$PYTHONPATH:. python examples/example_one.py 

首先,您应该避免使用与模块本身同名的文件。它可能会破坏其他导入。

当你导入一个文件时,解释器首先检查当前目录,然后搜索全局目录。

在示例或测试中,您可以调用:

from ..api import api