支持用yaml配置文件、对象、CLI参数。
安装:pip install omegaconf
导包
from omegaconf import OmegaConf
构建OmegaConf类
构建一个空的类
conf = OmegaConf.create() # {}
将Python字典转成OmegaConf类
conf = OmegaConf.create({"a": 1, "b": {"c": 2}})
"""
a: 1
b:c: 2
"""
将Python列表转成OmegaConf类
conf = OmegaConf.create([1, 2, {"a": [5, 6]}])
print(OmegaConf.to_yaml(conf))
print(type(conf))"""
- 1
- 2
- a:- 5- 6<class 'omegaconf.listconfig.ListConfig'>
"""
从YAML文件中加载OmegaConf类
conf = OmegaConf.load("a.yaml")
从命令行加载OmegaConf类
conf = OmegaConf.from_cli()# 外面的命令行代码:
# %run xxx.py server.port=8080 log.level=debug
从dataclass类中解析OmegaConf类
dataclass类
from dataclasses import dataclass @dataclass
class MyConfig: port: int = 80 # port of server host: str = "localhost" conf = OmegaConf.structured(MyConfig(port=443))
print(OmegaConf.to_yaml(conf))"""
port: 443
host: localhost
"""
其他基础操作
???占位符
yaml
server:port: 8080
log:level: debugfile: ??? # ???的作用,是占位符,用于表示一个未知的值
users:
- name: admin
- name: user
直接获取???会报错
需要先赋值再获取
conf = OmegaConf.load("a.yaml")conf.log.file = "log.log"
print(OmegaConf.to_yaml(conf))
修改原来的值
原来yaml里面有这个配置,想修改,直接赋值即可
# 修改原来的值
conf.server.port = 80
新增值
前提是有server这个前缀字段
# 新增一个值
conf.server.host = "0.0.0.0"
如果增加的是多个前缀,且文件中都没有就会报错(server没有会报错,如果是conf.host就没事)
# 但如果直接增加一个不存在的值,就会报错
conf.a.b = 1 # 会报错,因为没有a,所以无法增加b
使用update方法,可以增加一个不存在的值
# 使用update方法,可以增加一个不存在的值
OmegaConf.update(conf, "a.b.c", 1, force_add=True)
合并配置对象
# merge方法可以合并两个配置对象
conf1 = OmegaConf.create({"aaa": 1, "aab": 2})
conf2 = OmegaConf.create({"a": 1, "b": 2})
merged_conf = OmegaConf.merge(conf1, conf2)
存入yaml文件
with open("merged.yaml", "w") as f: OmegaConf.save(merged_conf, f)
值的引用
通过$实现
yaml文件:
server: host: localhost port: 80 client: url: http://${server.host}:${server.port}/ server_port: 80 description: Client of ${.url}
原生yaml是不支持引用的(某个值引用同个yaml中的其他值)的
import yaml
import pprint pp = pprint.PrettyPrinter(indent=4) # 打印时,缩进4个空格
with open("b.yaml", "r") as f: conf = yaml.safe_load(f)# 原生yaml是不支持引用的(某个值引用同个yaml中的其他值)的
conf["client"]["url"] # 'http://${server.host}:${server.port}/'
Omegaconf解析可以支持引用,但是是懒加载,直接输出整个文件并不会加载
# 用 OmegaConf 解析 yaml 文件
from omegaconf import OmegaConf with open("b.yaml", "r") as f: conf = OmegaConf.load(f) print(OmegaConf.to_yaml(conf)) # 这里还没有解析,是lazy loading
"""
server:host: localhostport: 80
client:url: http://${server.host}:${server.port}/server_port: 80description: Client of ${.url}
"""
单独输出引用的字段,会加载引用print(conf.client.url) # 'http://localhost:80/'
# 使用resolve方法,可以解析引用
OmegaConf.resolve(conf) # 递归地解析所有引用print(OmegaConf.to_yaml(conf)) # 现在已经解析了
