Python:临时合并几个配置字典,`ChainMap` 有时候挺顺手

13 次浏览1 条回复

小脚本里经常会有一层默认配置,再叠一层环境变量或命令行参数。只是临时读取的话,不一定非要马上复制合并一个新 dict,标准库的 collections.ChainMap 可以先顶一下。

环境:Python 3.8+。保存成 chainmap-demo.py

from collections import ChainMap

defaults = {
    'host': '127.0.0.1',
    'port': '8000',
    'debug': '0',
}

cli = {
    'port': '9000',
}

config = ChainMap(cli, defaults)

print(config['host'])
print(config['port'])
print(dict(config))

跑一下:

python chainmap-demo.py

能看到 port 用的是前面的 clihost 会从后面的默认值里找。

要注意它是“按层查找”的视图,不是深拷贝。后面的字典如果变了,读出来也会跟着变。配置很复杂、需要校验类型时,还是单独做配置解析更稳。

这个还有个小坑:如果后面想给某个 key 赋值,默认会写到第一层 map 里,不会改到后面的 defaults。

所以我一般只把它当“读配置”的临时视图用。真要落盘或者传给别的函数,先 dict(config) 固化一下会更不容易误会。