我正在编写一堆一起工作的Python脚本,例如tool1.py将一些数据加载到数据库表中,tool2.py从该表中读取数据,进行一些计算并将结果写入另一个表中,以及daemon1.py。 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
然后我使用命令
python tool1/tool1.py
运行我的工具和守护程序。然而,这里的问题是 tool1.py 如何访问 config.py/database.py。我考虑了以下选项,对 python 中被认为是“正确”的方式感兴趣,或者我可能错过的任何替代方案(可能是布置项目的不同方式)。提供权威答案的链接将获得额外的业力奖励。
sys
和 os
模块,除了设置这些项目外没有其他原因。 import os
import sys
sys.path.append(os.path.join(os.path.abspath(
os.path.dirname(__file__)), ".."))
from tool1dir import tool1
tool1.run()
在我的博客上写下了我的答案,但是我将在这里复制主要内容:
/README.md
/pyproject.toml
/my_project/
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
pyproject.toml
可能很小:
[project]
name = "my_project"
version = "0.1.0"
dependencies = [
...
]
现在 my_project/tool1/tool1.py
文件可以使用
from .. import database
但前提是它被称为模块。 为了将其作为模块调用,请安装它:
pip install .
(或
pip install -e .
以便在开发模式下安装它)。 现在
tool1
可以称为
python -m my_project.tool1.tool1
。您甚至可以更进一步,中定义您的入口点:
...
[project.scripts]
tool1 = "my_project.tool1.tool1:main"
这将(重新安装软件包后)允许在命令行上键入 tool1
,它将运行
main()
中的
my_project/tool1/tool1.py
函数。
另一个问题:
import sys
sys.path.insert(0,'..')
import database
可以通过添加以下内容将目录返回到其位置:
sys.path.insert(0,'tool1') #tool1 is replaced with your directory you are calling from.
使用第三种方法的变体来解决这个问题。