如何以Pythonic方式编写从环境变量读取常量的DRY代码?
Pythonic 读取环境变量作为模块常量的最佳实践
当然有更Pythonic且兼顾可读性的写法,既解决变量名重复问题,又能清晰展示模块可导出的常量,以下是几种常用方案:
方案1:封装辅助函数+显式赋值(轻量化首选)
通过封装一个获取环境变量的辅助函数,避免重复的错误处理逻辑,同时保持变量定义的直观性:
import os def _get_env_var(name): """内部辅助函数:获取环境变量,缺失则抛出明确错误""" try: return os.environ[name] except KeyError: raise EnvironmentError(f'环境变量 {name} 未定义') from None # 显式定义所有需要导出的常量 SETTING_A = _get_env_var('SETTING_A') SETTING_B = _get_env_var('SETTING_B') SETTING_C = _get_env_var('SETTING_C')
优点:
- 无额外依赖,代码简洁易懂
- 模块内的常量一目了然,其他开发者能快速知道可导入的内容
- 错误处理逻辑统一,避免重复代码
方案2:使用 dataclass 结构化管理(适合多配置场景)
利用Python标准库的dataclasses(3.7+),将配置项组织成不可变的结构化对象,同时保留类型提示:
import os from dataclasses import dataclass def _get_env_var(name): try: return os.environ[name] except KeyError: raise EnvironmentError(f'环境变量 {name} 未定义') from None @dataclass(frozen=True) # frozen=True 确保配置不可修改,符合常量特性 class Settings: SETTING_A: str = _get_env_var('SETTING_A') SETTING_B: str = _get_env_var('SETTING_B') SETTING_C: str = _get_env_var('SETTING_C') # 实例化后导出,使用时直接访问属性 settings = Settings()
使用方式:
from environment import settings print(settings.SETTING_A)
优点:
- 结构化管理配置项,适合配置较多的项目
- 自带类型提示,IDE能提供自动补全
- 冻结后的对象无法被意外修改,保证配置的稳定性
方案3:使用 pydantic-settings(复杂项目首选)
如果需要类型校验、默认值、嵌套配置等高级功能,推荐使用pydantic-settings(原Pydantic的BaseSettings),它会自动从环境变量读取配置,并提供强大的校验能力:
# 先安装依赖:pip install pydantic-settings from pydantic_settings import BaseSettings class Settings(BaseSettings): # 直接定义字段,自动对应同名环境变量 SETTING_A: str SETTING_B: str SETTING_C: str settings = Settings()
优点:
- 自动读取环境变量,无需手动调用
os.environ - 支持类型校验,比如字符串转整数、布尔值等
- 可设置默认值、嵌套配置、环境变量前缀等高级特性
- 缺失配置时会抛出清晰的错误信息
为什么不推荐你的原有方案?
- 方法1:重复代码过多,每个变量都要写一遍
os.environ和错误捕获逻辑,维护成本高 - 方法2:直接操作
locals()不直观,其他开发者无法快速知道模块导出哪些常量;且在某些Python解释器环境下,模块级别的locals()修改可能不生效,存在隐性问题
内容的提问来源于stack exchange,提问作者actual_panda
相关产品推荐
相关产品推荐

