Python读取配置文件,最实用的方案是根据项目场景选择configparser、PyYAML或json模块,其中configparser适合标准INI格式,PyYAML适合复杂嵌套结构,json适合跨语言交换,日常开发中约八成需求用这三种即可覆盖。

python读取配置文件用什么库最合适
很多朋友第一次接触配置文件时,习惯把配置直接写死在代码里,这种做法在脚本阶段没什么问题,但项目一上线,数据库密码、接口地址、日志级别这些东西全混在业务代码里,改一次配置就得重新部署一次,非常被动。
行业共识认为,配置文件的核心价值是把可变参数与静态逻辑分离,Python生态里,处理配置文件的主流工具就三个:configparser(标准库)、PyYAML(第三方)、json(标准库),你不需要全掌握,但至少要清楚各自擅长什么。
| 库名称 | 配置格式 | 适用场景 | 学习成本 |
|---|---|---|---|
| configparser | INI | 简单键值对、分节管理 | 极低 |
| PyYAML | YAML | 嵌套数据结构、复杂业务配置 | 中等 |
| json | JSON | 跨语言、前后端统一 | 极低 |
对于中小型项目,如果你问python读取配置文件用什么库最合适,我的建议是:能用标准库解决的,就别急着装第三方依赖。configparser 是Python自带的,不需要 pip install,拿来就能用。
配置文件写在python文件里面还是外部文件
这个问题每年都有新手问,先给结论:业务配置必须放外部文件,原因很简单你的代码要进版本库,但数据库密码、API密钥这些敏感信息不能跟着代码一起提交,放在外部配置文件中,配合 .gitignore 忽略掉,才能保证安全。
外部配置文件的管理方式,业内一般遵循这样的路径:
- 开发环境用
config_dev.ini,连接本地数据库 - 测试环境用
config_test.ini,使用独立测试库 - 生产环境用
config_prod.ini,对应正式服务器资源
代码里只需要指定当前环境变量,os.environ.get('RUN_ENV', 'dev'),就能动态加载对应配置,如果配置项比较少,也可以把配置文件写在Python文件里,通过 from config import 导入,这种做法适合个人小工具或脚本,但不适合多人协作的工程化项目。
configparser读取INI配置文件的实战操作
INI格式长什么样?看这个例子:
[database] host = 127.0.0.1 port = 3306 username = admin password = secret123 [redis] host = 127.0.0.1 port = 6379 db = 0
读取这段配置的代码只需要六行:
import configparser
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')
db_host = config.get('database', 'host')
db_port = config.getint('database', 'port')
注意 getint() 这个细节,它会把字符串 3306 自动转成整数类型,省去手动 int() 转换的麻烦,类似的方法还有 getboolean() 和 getfloat(),分别对应布尔值和浮点数。
如果配置文件的键值对包含中文,一定要在 read() 时指定 encoding='utf-8',否则在Windows环境下容易触发 UnicodeDecodeError 报错。
当键不存在时,config.get() 会抛异常,更稳妥的写法是:
db_host = config.get('database', 'host', fallback='localhost')
这样就算配置缺失,程序也不会直接崩溃,而是用默认值兜底。
PyYAML读取YAML配置文件的完整流程
YAML的颜值比INI高很多,尤其是处理多层嵌套的配置结构时,缩进式的层级关系一目了然,一个典型的YAML配置长这样:
app:
name: user-service
port: 8080
debug: true
database:
mysql:
host: 10.0.0.1
port: 3306
pool_size: 20
redis:
host: 10.0.0.2
port: 6379
使用PyYAML读取,需要先安装依赖库:
pip install pyyaml
读取代码也非常简洁:

import yaml
with open('config.yaml', 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
mysql_host = config['database']['mysql']['host']
pool_size = config['database']['mysql']['pool_size']
yaml.safe_load() 是官方推荐的加载方式,它会忽略YAML中潜在的任意对象构造,避免安全问题,千万别用 yaml.load() 不带参数的形式,那等于把系统安全拱手让人。
YAML对缩进极其敏感,两个空格是约定俗成的缩进单位,多一个空格或少一个空格都会导致解析失败,如果你在调试时遇到 yaml.scanner.ScannerError,优先检查缩进是否对齐。
json模块读取配置文件的差异分析
JSON格式最大的优势是通用性,前端、后端、移动端都能解析JSON,很多云服务的SDK也直接返回JSON格式的配置信息。
{
"service": {
"name": "api-gateway",
"port": 8080,
"timeout": 30
},
"log": {
"level": "info",
"path": "/var/log/app.log"
}
}
读取代码:
import json
with open('config.json', 'r', encoding='utf-8') as f:
config = json.load(f)
service_name = config['service']['name']
log_level = config['log']['level']
JSON不支持注释,这是它和INI、YAML相比最明显的短板,配置文件一旦复杂起来,开发人员会非常怀念能写注释的格式。
三种格式的python读取配置文件对比,可以这样总结:
- INI:上手最快,支持注释,适合扁平化配置,嵌套表达弱
- YAML:结构性最强,适合微服务架构中的复杂配置,但缩进容易出错
- JSON:跨语言兼容最好,但不支持注释,多余逗号会直接报错
Python读取配置文件的常见报错及解决办法
FileNotFoundError,文件路径找不到,检查 read() 或 open() 中填的路径是相对路径还是绝对路径,建议在代码里先打印当前工作目录:
import os print(os.getcwd())
然后根据实际输出调整路径。
KeyError,键不存在,多半是配置文件的section名或键名写错了,注意大小写敏感,可以使用 config.has_section() 或 has_option() 预先判断。
encoding报错,中文配置读取乱码,在打开文件时统一定义 encoding='utf-8',并确保编辑器保存文件时也是UTF-8编码,Windows记事本默认会存成GBK,这个坑相当多人踩过。
yaml.scanner.ScannerError,YAML格式错误,检查冒号后是否跟了空格,缩进是否统一为两个空格,特殊符号有没有加引号。password: abc@123,其中的 一般没问题,但如果包含 冒号就必须用引号包裹。
python读取配置文件并写入日志的实用场景
配置文件读出来之后,下一步通常就是接入日志系统,这里给一个最小可用的组合示例:
import configparser
import logging
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')
log_level = config.get('log', 'level', fallback='INFO')
log_file = config.get('log', 'file', fallback='app.log')
logging.basicConfig(
level=getattr(logging, log_level.upper()),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(log_file, encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger('my_app')
logger.info('配置文件加载成功')
这个模式的好处是,运维人员无需修改代码,只需要编辑配置文件中的日志级别,就能动态调整日志输出量,排查问题时把 INFO 改成 DEBUG,问题定位后再改回来。
python自动化测试框架中配置文件如何设计
自动化测试项目对配置文件的需求,要比普通业务项目更敏感,测试环境随时可能切换,测试数据要定期清理,配置管理跟不上,整个测试流程就会卡壳。
推荐的做法是按环境拆分配置文件:

config/ ├── base.ini ├── dev.ini ├── staging.ini └── prod.ini
base.ini 放所有环境共用的配置,各个环境文件只写差异项,读取时先加载 base.ini,再加载对应环境文件覆盖同名键:
config = configparser.ConfigParser()
config.read('config/base.ini', encoding='utf-8')
config.read(f'config/{env}.ini', encoding='utf-8')
configparser的 read() 支持传入多个文件路径,后者会自动覆盖前者的同名键值,这个特性在测试多环境切换时非常顺手。
如何用Python动态生成配置文件
除了读取,程序运行时也需要把配置写回文件,比如自动化测试执行完,需要记录测试报告路径、运行耗时等信息,configparser同样支持写入:
import configparser
config = configparser.ConfigParser()
config['report'] = {
'path': 'reports/2026_01_15.html',
'duration': '32.5s',
'passed_cases': '108'
}
with open('run_result.ini', 'w', encoding='utf-8') as f:
config.write(f)
PyYAML写YAML文件也简单:
import yaml
data = {'report': {'path': 'reports/2026_01_15.html', 'duration': '32.5s'}}
with open('run_result.yaml', 'w', encoding='utf-8') as f:
yaml.dump(data, f, allow_unicode=True, default_flow_style=False)
allow_unicode=True 这个参数重要,不然中文内容会被转成 \uXXXX 的Unicode转义序列,可读性很差。
数据刷新机制方面,多数项目在服务启动时加载一次配置常驻内存,如果你的配置需要热更新,可以在每次请求时重新读取文件,或者加一个定时任务每隔一段时间刷新一次,高频读写场景下,文件I/O毕竟是瓶颈,但绝大多数配置场景的刷新频率远远触达不到这个瓶颈。
Q&A:python读取配置文件时容易踩的坑
Q:读取配置文件时相对路径总报错怎么办?
A:使用 pathlib 定位项目根目录,再拼接配置路径:
from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent CONFIG_FILE = BASE_DIR / 'config' / 'config.ini' config.read(CONFIG_FILE, encoding='utf-8')
这样无论程序从哪个目录启动,都能准确找到配置文件位置。
Q:配置文件中的敏感信息如何保护?
A:不要把明文密码直接写在配置文件里,在配置文件中使用环境变量占位符,代码中从环境变量读取真实值,具备一定规模的团队大多会采用这种间接方式,纯粹依赖配置文件存放密钥,一旦仓库泄露等于把所有密码公之于众。
Q:YAML配置解析慢不慢?
A:相比JSON,YAML解析确实稍慢,毕竟语法更复杂,但配置文件的体积通常只有几KB到几十KB,解析耗时在毫秒级别,对性能的实际影响可以忽略不计,如果你的配置量达到数万行,那更值得关注的是配置本身的设计,而非解析速度。
