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

结构如下:

├── 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中完成,对吧?


当前回答

对于主要问题:

调用兄弟文件夹作为模块:

从. .进口siblingfolder

从兄弟文件夹调用a_file.py作为模块:

从. .兄弟文件夹导入a_file

在兄弟文件夹中的文件中调用a_function作为模块:

从. . siblingmodule。A_file import func_name_exists_in_a_file

最简单的方法。

进入lib/site-packages文件夹。

如果存在“easy_install.pth”文件,只需编辑它并添加您有脚本的目录,将其作为模块。

如果不存在,就把它变成一个…把你想要的文件夹放在那里

添加之后…, python会自动将该文件夹视为类似site-packages的文件夹,您可以将该文件夹或子文件夹中的每个脚本作为模块调用。

这是我用手机写的,很难设置成让每个人都能舒服地阅读。

其他回答

对于兄弟包导入,您可以使用[sys. xml]的insert或append方法。路径][2]模块:

if __name__ == '__main__' and if __package__ is None:
    import sys
    from os import path
    sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
    import api

如果你启动你的脚本,这将工作如下:

python examples/example_one.py
python tests/test_one.py

另一方面,你也可以使用相对导入:

if __name__ == '__main__' and if __package__ is not None:
    import ..api.api

在这种情况下,你必须使用'-m'参数启动你的脚本(注意,在这种情况下,你不能给出'.py'扩展名):

python -m packageName.examples.example_one
python -m packageName.tests.test_one

当然,你可以混合使用这两种方法,这样你的脚本无论如何调用都能正常工作:

if __name__ == '__main__':
    if __package__ is None:
        import sys
        from os import path
        sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
        import api
    else:
        import ..api.api

如果您正在使用pytest,那么pytest文档描述了如何从单独的测试包引用源包的方法。

建议的项目目录结构为:

setup.py
src/
    mypkg/
        __init__.py
        app.py
        view.py
tests/
    __init__.py
    foo/
        __init__.py
        test_view.py
    bar/
        __init__.py
        test_view.py

setup.py文件的内容:

from setuptools import setup, find_packages

setup(name="PACKAGENAME", packages=find_packages())

以可编辑模式安装软件包:

pip install -e .

这篇文章引用了Ionel Cristian matrie什的博客文章。

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

文档

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

我还没有对python学有必要的理解,以了解在不相关的项目之间共享代码的预期方式,而没有兄弟姐妹/亲戚导入黑客。在那一天到来之前,这就是我的解决方案。用于从..导入内容的示例或测试。\api,它看起来像:

import sys.path
import os.path
# Import from sibling directory ..\api
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/..")
import api.api
import api.api_key