如何用python-dotenv实现默认环境变量与.env文件覆盖配置?
开箱即用Python包的环境变量配置最优实现
核心逻辑
优先使用预设的默认配置,当用户目录下存在.env文件时,用其中的配置覆盖对应默认值——无需用户额外配置即可跑通,又支持灵活的环境定制。
实现步骤(基于python-dotenv)
添加依赖
把python-dotenv加到包的依赖列表中,用户安装包时会自动安装:# pyproject.toml示例 [project] dependencies = ["python-dotenv>=1.0.0"]定义默认配置
在包的配置模块(比如your_package/config.py)里写死合理的默认值:DEFAULT_CONFIG = { "SERVER": "localhost", "PORT": 8000, "DEBUG": False, "API_TIMEOUT": 30 }加载并合并配置
使用load_values方法加载.env(无文件时返回空字典,不会抛出异常),然后覆盖默认配置,同时处理类型转换(因为.env里的所有值都是字符串):from dotenv import load_values # 加载.env配置,无文件则返回空字典 env_vars = load_values(".env") # 合并配置:.env变量覆盖默认值 config = DEFAULT_CONFIG.copy() for key, val in env_vars.items(): if key not in config: continue # 根据默认值类型做转换 default_type = type(config[key]) if default_type is int: config[key] = int(val) elif default_type is bool: # 兼容true/false、True/False、1/0等写法 config[key] = val.strip().lower() in ("true", "1") else: config[key] = val如果你更习惯用系统环境变量的方式,也可以用
load_dotenv配合os.getenv实现:import os from dotenv import load_dotenv # 加载.env到系统环境变量,无文件时无操作 load_dotenv() config = { "SERVER": os.getenv("SERVER", DEFAULT_CONFIG["SERVER"]), "PORT": int(os.getenv("PORT", DEFAULT_CONFIG["PORT"])), "DEBUG": os.getenv("DEBUG", str(DEFAULT_CONFIG["DEBUG"])).strip().lower() in ("true", "1"), "API_TIMEOUT": int(os.getenv("API_TIMEOUT", DEFAULT_CONFIG["API_TIMEOUT"])) }在包中使用配置
其他模块直接导入配置字典即可:from your_package.config import config def connect_server(): print(f"连接到 {config['SERVER']}:{config['PORT']},超时时间 {config['API_TIMEOUT']}s")
注意事项
- 类型转换不可少:
.env中所有值都是字符串,必须根据默认值的类型做转换,避免出现字符串端口、布尔值判断错误等问题。 - 排除.env文件:在
MANIFEST.in或pyproject.toml中添加排除规则,不要把示例.env或用户的.env打包进PyPI包:# MANIFEST.in示例 exclude .env exclude .env.example - 文档说明:在包的README里列出所有可配置的环境变量、默认值和用途,方便用户自定义。
内容的提问来源于stack exchange,提问作者FordPrefect
相关产品推荐
相关产品推荐

