了解 python 导入系统和项目结构

Understanding python import system and project structuring

假设我有一个组织如下的项目:

ProjectRoot/
    __init__.py
    test.py
    A/
        __init__.py
        a_test.py
    B/
        __init__.py
        b_test.py

并假设 a_test 依赖于 b_test。所以源码比较简单:

#
# a_test.py
#

from B.b_test import b_test_class

class a_test_class:
    def func(self):
        print("a_test_class")
        b_instance = b_test_class()
        b_instance.func()


if __name__ == "__main__":
    a_instance = a_test_class()
    a_instance.func()

#
# b_test.py
#

class b_test_class:
    def func(self):
        print("b_test_class")

#
# test.py
#

from A.a_test import a_test_class

if __name__ == "__main__":
    a_instance = a_test_class()
    a_instance.func()

只要我启动 test.py 脚本,一切都会按预期进行。 Python 毫无问题地加载所有模块并执行它们。现在问题来了: 如何在没有 test.py 的情况下启动 a_test.py? 所以,基本上,我想要的实现就是cd进projectRoot/A然后执行a_test.py。这导致得到 ImportError: No module named 'B'

目前我已经能够创建具有以下结构的项目:

ProjectRoot/
    customLibModuleA/
        ...
    customLibModuleB/
        ...
    mainApp.py

我希望能够创建的内容如下:

ProjectRoot/
    customLibModuleA/ #custom protocol implementation
        ...
    customLibModuleB/ #custom logging functions
        ...
    application1/ #server
        ...
    application2/ #client
        ...

我希望如何管理复杂的项目?欢迎任何对项目结构手册和样式指南的良好参考。

这是我的临时解决方案,因为没有人提供 pythonic 方法。

文件夹结构如下所示:

ProjectRoot/
    __init__.py
    customLibModuleA/ #custom protocol implementation
        __init__.py
        ...
    customLibModuleB/ #custom logging functions
        __init__.py
        ...
    application1/ #server
        __init__.py
        __path_setup__.py
        server.py
        ...
    application2/ #client
        __init__.py
        __path_setup__.py
        client.py
        ...

__path_setup__.py内容为:

import sys
import os

os.sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))

应用程序脚本在导入之前有一些设置代码 (server.py):

#
#settings up the environment
#
if __name__ == "__main__":
    exec(open("./__path_setup__.py").read())

#
# system and libraries imports
#
import customLibModuleA.whatever
...

仍然欢迎针对此问题的高质量 pythonic 解决方案。