Python脚本如何读取本地配置文件

wen python案例 28

Python脚本如何读取本地配置文件:从入门到生产级实战

目录导读

  1. 为什么需要配置文件? — 项目可维护性与环境分离的核心思想
  2. 主流配置文件格式对比 — INI、JSON、YAML、TOML 选型指南
  3. Python内置模块实战configparser 读取 INI 文件全流程
  4. JSON配置读取与异常处理 — 适合API交互场景的最简方案
  5. YAML配置读取 — 借助 PyYAML 实现复杂层级配置
  6. 环境变量与配置文件协同 — 敏感信息不硬编码的进阶技巧
  7. 常见问题与解决方案 — 编码、路径、热加载等痛点修复
  8. 生产环境最佳实践 — 配置校验、加密与多环境管理

为什么需要配置文件?

问:脚本写得好好的,为什么非要搞个配置文件?
答: 假设你的脚本连接数据库时,密码写死在代码里,一旦密码变更,你需要改代码、重新部署、重启服务,而使用配置文件后,只需修改一个外部文件,无需触碰核心逻辑,这叫配置与代码分离,是构建可维护系统的第一原则。

Python脚本如何读取本地配置文件

配置文件的核心价值在于:

  • 环境隔离:开发、测试、生产环境使用不同配置(数据库地址、API密钥等)
  • 扩展性:新增参数(如日志级别、超时时间)无需修改代码
  • 安全合规:敏感信息可通过环境变量或加密文件注入,而非提交到版本库

主流配置文件格式对比

问:Python支持那么多格式,该选哪种?
答: 根据项目规模与团队习惯选择,以下是四种常见格式的对比表:

格式 适用场景 优点 缺点 标准库支持
INI 简单项目、传统应用 结构直观,Python内置configparser 不支持复杂嵌套
JSON Web项目、API接口 序列化方便,易与其他语言交互 写起来啰嗦,不支持注释
YAML 大数据、DevOps、Kubernetes 层级清晰,支持注释与引用 缩进敏感,需第三方库 ❌(需PyYAML
TOML 现代项目(如pip配置) 明确的数据类型,可读性强 社区使用度较低 ✅(Python3.11+)

小原则

  • 如果你写的是十行以内的脚本 → INI 或 JSON
  • 如果你在写企业级服务 → YAML 或 TOML

Python内置模块实战:读取INI文件

问:INI配置文件长什么样?
答: 见下方示例 config.ini

[DEFAULT]
log_level = INFO
timeout = 30
[database]
host = 127.0.0.1
port = 5432
user = admin
password = secret123

Python脚本读取代码:

import configparser
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')
# 读取数据库配置
db_host = config['database']['host']
db_port = config.getint('database', 'port')  # 自动转为int
log_level = config['DEFAULT']['log_level']
print(f"连接数据库:{db_host}:{db_port}")

注意点:

  • read() 可传入 list 路径,优先读取存在的文件
  • 一定要指定 encoding='utf-8',否则中文路径或注释可能报错
  • [DEFAULT] 节下的配置会作为其他节的默认值,无需重复定义

JSON配置读取与异常处理

问:JSON配置文件怎么读更安全?
答: config.json 内容示例:

{
  "server": {
    "host": "0.0.0.0",
    "port": 8000,
    "cors": ["https://example.com"]
  }
}

Python脚本:

import json
from pathlib import Path
config_path = Path('config.json')
if not config_path.exists():
    raise FileNotFoundError(f"配置文件 {config_path} 不存在")
try:
    with open(config_path, 'r', encoding='utf-8') as f:
        config = json.load(f)
except json.JSONDecodeError as e:
    print(f"配置解析失败:{e}")
    exit(1)
port = config.get('server', {}).get('port', 8080)
print(f"服务端口:{port}")

关键优化:

  • 使用 .get() 方法避免 KeyError,并设置默认值
  • Path 处理路径,跨系统更安全
  • 解析失败时给出明确错误信息,方便调试

YAML配置读取:复杂层级的最佳选择

问:YAML配置文件怎么读取?
答: 需要安装 PyYAML 库:pip install pyyaml,配置文件 config.yaml

database:
  host: 192.168.1.100
  port: 5432
  pool_size: 10
  options:
    connect_timeout: 5
    keepalives: true
logging:
  level: DEBUG
  file: /var/log/app.log

Python读取代码:

import yaml
with open('config.yaml', 'r', encoding='utf-8') as f:
    config = yaml.safe_load(f)  # 推荐使用 safe_load 而非 load
db_host = config['database']['host']
timeout = config['database']['options']['connect_timeout']

常见坑:

  • 永远使用 yaml.safe_load(),不要用 yaml.load(),后者可能执行任意代码
  • YAML对缩进极其敏感,建议用编辑器格式化
  • 支持 注释,非常适合大型配置文档

环境变量与配置文件协同

问:配置文件中有密码,提交到GitHub怎么办?
答: 核心策略——配置文件存结构,环境变量存敏感值

配置模板 + .env 文件
新建 config.template.json

{
  "database": {
    "host": "localhost",
    "user": "admin",
    "password": "${DB_PASSWORD}"
  }
}

使用 os.environ 读取环境变量:

import os, json
with open('config.json') as f:
    raw = f.read()
    # 替换 ${KEY} 格式的占位符
    for key, value in os.environ.items():
        raw = raw.replace(f'${{{key}}}', value)
config = json.loads(raw)

使用 python-dotenv(推荐)
创建 .env 文件(绝不可提交):

DB_PASSWORD=real_secret_123

代码中加入加载逻辑:

from dotenv import load_dotenv
load_dotenv()  # 自动加载 .env 文件到环境变量
db_password = os.getenv('DB_PASSWORD')

最佳实践:
config.template.json.env.example 提交到Git,真正的 .envconfig.json 加入 .gitignore


常见问题与解决方案

问题1:配置文件路径总是找不到?
解决方案: 使用 __file__ 获取脚本所在路径:

from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
config_path = BASE_DIR / 'config.ini'

问题2:读取中文配置时报错?
解决方案: 始终以 encoding='utf-8' 打开文件,如果文件是 GBK 编码,需指定 encoding='gbk'

问题3:配置修改后脚本不生效?
解决方案: 配置文件通常是程序启动时一次读取,若需热加载,可定时检查文件修改时间:

import os, time
last_mtime = 0
def check_config():
    global config, last_mtime
    mtime = os.path.getmtime('config.ini')
    if mtime > last_mtime:
        config = configparser.ConfigParser()
        config.read('config.ini')
        last_mtime = mtime

问题4:JSON文件不支持注释?
解决方案: 使用 JSON 格式时,可以在读取前用正则忽略以 或 开头的行,但更推荐改用 YAML。


生产环境最佳实践

配置校验是必须的
使用 pydantic 库定义配置模型的类型与约束:

from pydantic import BaseModel, Field
class DatabaseConfig(BaseModel):
    host: str
    port: int = Field(5432, ge=1024, le=65535)
    password: str = Field(min_length=8)
class AppConfig(BaseModel):
    database: DatabaseConfig
# 读取文件并校验
config = yaml.safe_load(open('config.yaml'))
validated_config = AppConfig(**config)

敏感配置应加密
对密码或密钥使用 cryptography 库进行对称加密,运行时解密。

多环境管理方案
项目目录结构推荐:

project/
├── config/
│   ├── base.yaml          # 公共配置
│   ├── development.yaml   # 开发环境覆盖
│   ├── production.yaml    # 生产环境覆盖
├── .env.development       # 开发环境变量
├── .env.production        # 生产环境变量

启动时根据 ENV 环境变量合并配置:

import os
env = os.getenv('APP_ENV', 'development')
# 合并 base 与对应环境配置

版本库中只存模板

# .gitignore 中必须包含:
config.json
.env
*.key

Python脚本读取配置文件看似简单,但做好却需要考量编码、路径、安全、多环境等多方面因素,从最初的 configparser 到现代项目的 pydantic + yaml + env 组合,核心目标始终是将可变部分抽离出来,确保代码的稳定与安全,希望这篇文章能帮你建立一套可落地的配置管理思路。

如果你在实际项目中遇到特殊的配置读取需求(如远程配置中心、动态配置刷新),欢迎在评论区留言讨论。

抱歉,评论功能暂时关闭!