4

优雅地加载Yaml配置文件

 2 years ago
source link: https://developer.51cto.com/article/707043.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
优雅地加载Yaml配置文件-51CTO.COM
优雅地加载Yaml配置文件
作者:Kingname 2022-04-20 20:27:51
今天我们来介绍一个先进的工具,专门用来高效加载配置文件。这就是Facebook开源的Hydra。

我在多篇文章里面都说过,我非常喜欢使用Yaml格式来写配置文件,Yaml是一个对人非常友好的配置格式。

951e5713981da456d9c1245d434caa73b54f92.jpg

有时候,我们在开发环境、测试环境和线上环境会有多套不同的配置文件,如何在不修改代码的情况下方便的切换配置文件呢?我以前的文章讲过一种方法,使用环境变量来指定配置文件名。今天我们来介绍一个更先进的工具,专门用来高效加载配置文件。这就是Facebook开源的Hydra。

这个工具有多简单呢?我们先写两个配置文件,然后看看怎么读取它:

36e8b4749be9e3e7265160f732d3a5a9ac50e0.png

使用pip安装Hydra:

python3 -m pip install hydra-core

接下来,我们写一段代码,来读取配置文件:

import os
import hydra
from omegaconf import DictConfig

env = os.getenv('DATA_CENTER', 'dev')
@hydra.main(config_path="config", config_name=env)
def main(cfg: DictConfig):
    print('MongoDB链接地址是:', cfg.mongo.uri)
    print('Redis的key是:', cfg.redis.key)
    print('黑名单是:', cfg.detail.black_list)


if __name__ == '__main__':
    main()

运行效果如下图所示:

b82af7943ff53ea39eb36105e410518786aebf.png

其中,装饰器hydra.main的参数config_path指定存放配置文件的文件夹,config_name用来指定配置文件的名字(去掉.yaml)。

这样一来,我们可以通过环境变量指定要使用哪个配置文件。

这样看起来似乎跟我以前讲的方法没什么区别啊。那么,高级的功能来了。例如现在我使用dev环境时,临时想修改一下Redis的Key怎么办呢?以前的方法,我就必须去修改Yaml文件,把Key改掉。但是,既然是临时修改,测试完了又要改回来,显然非常麻烦。

使用Hydra,这个问题就不再是问题了。我们来看看直接在命令中覆盖数据的方法:

656e2bd059003938c514744517dc128c0e78de.png

请看图中,我代码没有做任何修改,Yaml也没有做任何修改。只需要在启动命令的时候增加一个参数redis.key=new_key,那么程序读取到的就是新的值了。这对临时测试的时候非常有用。

除了我上面介绍的这些,Hydra还可以实现自动补全,自动提示参数名,自动以多个不同的配置连续运行等等功能。

最后,我补充一个点。有同学在公众号粉丝群提问,Hydra为什么不能在调用函数的时候,传递额外的参数,例如下面这样写就会报错:

d543bfe05ddade10e2d496fcbb62a9c75d2914.png

这是因为,Hydra的装饰对象应该是程序的入口函数。给入口函数传递参数是很奇怪的。如果你的入口函数要根据参数的不同值执行不同的逻辑,那么这个参数你完全可以放到配置文件中。而不是用函数参数来传入。

所以,这里报错应该是功能而不是bug。本来就不应该在入口函数中添加额外的参数。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK