具有多个入口点和集中(配置)文件的结构 python 项目

Cla*_*ude 5 python

我正在编写一堆一起工作的 python 脚本,例如 tool1.py 将一些数据加载到数据库表中,tool2.py 从此表中读取数据,进行一些计算并将结果写入另一个表中,以及 daemon1.py是一个提供结果的网络服务器。每个工具和守护程序都有一大堆支持文件(仅该一个工具需要),并且需要自己的目录。此外,我确实有一些在所有工具之间共享的代码,例如config.py和database.py。直觉上,我是这样构建该项目的:

/README.md
/requirements.txt
/config.py # contains shared configuration
/database.py # shared code to connect to the database
/tool1/
    tool1.py # entrypoint
    [...] # bunch of other files only needed by tool1
/tool2/
    tool2.py #entrypoint
    [...] # bunch of other files only needed by tool2
/deamon1/
    daemon1.py #entrypoint
    [...] # bunch of other files only needed by daemon1
Run Code Online (Sandbox Code Playgroud)

然后,我使用命令运行我的工具和守护程序python tool1/tool1.py。然而这里的问题是 tool1.py 如何访问 config.py/database.py。我考虑了以下选项,对 python 中被认为是“正确”的方式感兴趣,或者我可能错过的任何替代方案(可能是布置项目的不同方式)。提供权威答案的链接将获得额外的业力奖励。

  1. 将 config.py/database.py 文件符号链接到子目录中。不太喜欢它,因为它让我的编辑感到困惑,并且似乎使事情变得不必要的复杂。
  2. 在某个单独的包中制作 config.py/database.py ,我将其安装在我的 virtualenv 中。不喜欢它,因为我也经常更改这些文件,并且我想将它们保留在同一个 git 存储库中。
  3. 更改 tool1.py 顶部的 sys.path。这会导致每个文件的顶部有 4 行,再加上导入sysos模块,除了设置这些项目外没有其他原因。
/README.md
/requirements.txt
/config.py # contains shared configuration
/database.py # shared code to connect to the database
/tool1/
    tool1.py # entrypoint
    [...] # bunch of other files only needed by tool1
/tool2/
    tool2.py #entrypoint
    [...] # bunch of other files only needed by tool2
/deamon1/
    daemon1.py #entrypoint
    [...] # bunch of other files only needed by daemon1
Run Code Online (Sandbox Code Playgroud)
  1. 将顶级路径添加到 $PYTHONPATH
  2. 为 tool1.py/tool2.py/daemon1.py 创建顶级入口点,其内容类似于(将 tool1 目录重命名为 tool1dir 后)
import os
import sys
sys.path.append(os.path.join(os.path.abspath(
    os.path.dirname(__file__)), ".."))
Run Code Online (Sandbox Code Playgroud)
  1. 将 config.py/database.py 放入单独的包中,并从每个 subdir 符号链接该目录

如前所述,想听听Python式的方法来做到这一点,或者任何建议或偏好。

Duc*_*sEL -1

来自 Shinbero 的另一个问题

import sys
sys.path.insert(0,'..')
import database
Run Code Online (Sandbox Code Playgroud)

可以通过添加以下内容将目录返回到其位置:

sys.path.insert(0,'tool1') #tool1 is replaced with your directory you are calling from.
Run Code Online (Sandbox Code Playgroud)

使用第三种方法的变体来解决这个问题。