Python 现代开发学习笔记

(二十二)把配置、程序与运行数据分开

书目数据库位置、采集来源和模型根目录都可能随运行环境改变。把它们作为配置传入,清洗函数和查询逻辑就不需要为每台机器修改。

# 项目文件:catalog_project/src/cataloghub/config.py
from dataclasses import dataclass
import os
from pathlib import Path


@dataclass(frozen=True)
class Settings:
    database: Path
    archives: Path
    source: str

    @classmethod
    def from_env(cls):
        # 运行数据放在实例目录,源码和安装包都不写入本机状态。
        return cls(
            Path(os.getenv("CATALOG_DB", "instance/catalog.sqlite3")).resolve(),
            Path(os.getenv("CATALOG_ARCHIVES", "instance/archives")).resolve(),
            os.getenv("CATALOG_SOURCE", "http://127.0.0.1:8780/catalog?page=1"),
        )

os.getenv() 从当前进程环境读取值,未设置时采用后面的默认值。相对路径在启动时转成绝对路径;在不同工作目录启动,解释后的相对路径也不同。部署时直接使用明确的绝对位置,更容易核对数据究竟保存在哪里。

# 项目文件:catalog_project/.env.example
# 将这些值设为进程环境变量;本项目不会自动读取 .env。
CATALOG_DB=instance/catalog.sqlite3
CATALOG_ARCHIVES=instance/archives
CATALOG_SOURCE=http://127.0.0.1:8780/catalog?page=1
LOG_LEVEL=INFO

.env.example 是配置示例。直接运行本项目时,进程不会自动读取名叫 .env 的文件,先在终端设置环境变量即可。后面 Compose 的 environment 则显式传入容器进程。

# 在 catalog_project 中给接下来的迁移、采集与服务选择同一个数据目录。
$env:CATALOG_DB = (Join-Path (Get-Location) 'instance/catalog.sqlite3')
$env:CATALOG_ARCHIVES = (Join-Path (Get-Location) 'instance/archives')
uv run catalog migrate
uv run catalog collect

模型项目对应使用 MODEL_ROOT;MODEL_VERSION 有值时固定选择该版本,否则启动时读取 current.json。例如复查旧模型时,可以显式指定 v1,然后从 /model 核对真正加载的结果。

# 项目文件:model_project/.env.example
# 将这些值设为进程环境变量;本项目不会自动读取 .env。
MODEL_ROOT=models
# MODEL_VERSION=v1 可固定加载某个版本;省略时读取 current.json。
LOG_LEVEL=INFO

源码与模板进入版本管理;.venv 由锁定文件重建;instance 和 models 是需要保留的运行状态。把这三类内容分清后,更换应用代码、重建解释器环境和恢复数据就有各自明确的输入。

笔记正文与全部题解 · Ctrl / ⌘ K