根据 argparser 参数在运行时更新 YAML 配置文件
Update YAML config files at runtime based on argparser arguments
我有一个 .yml 配置文件,它根据我 运行 的客户端控制我的程序的所有文件 I/O。客户端名称应位于 YAML 文件中给出的路径中的某处,例如:
client: CLIENT_1
data:
raw-file-path: D://Users//product//data//raw//CLIENT_1//CLIENT_1_data.csv
processed-data-file-path: D://Users//product//data//processed//CLIENT_1//CLIENT_1_processed_data.csv
有多个客户端,它们的数据始终位于指定的子目录中。我的代码为每个客户端提取原始数据,并在适当的目录中生成处理后的数据,如上例所示。在大多数情况下,我想 运行 单个客户端的脚本,因此我可以编辑我显示的 config.yml
文件,但我希望能够以编程方式进行。我在 ArgumentParser 中添加了一个 --clients
参数:parser.add_argument('--clients', nargs='+', default=[], help='list of clients')
以允许将客户端列表作为输入给出,例如 python run.py --config config.yml --clients CLIENT_1 CLIENT_2
我想找到一种方法来操纵所有这些路径以指向适当的目录,甚至可以利用类似 f-strings 的东西命名文件,但我不知道该怎么做。我发现最接近的问题是这个问题:,但它指的是我不熟悉的 Jinja2 模板。有更简单的方法吗?
有一个 Python 包可用于从 YAML/JSON/dicts 巧妙地构造对象,并且正在积极开发和扩展。 (完全公开,我是这个包的合著者,参见here)
此外,还有用于传递参数的选项,请参阅 this
然后你可以在 YAML 中定义它:
some_field: _|arg_name|_
并像这样加载它:
test_conf_yaml = PickleRick('./tests/placebos/test_config.yaml', arg_name='hallo world')
安装:
pip install pickle-rick
使用:
定义 YAML 或 JSON 字符串(或文件)。
BASIC:
text: test
dictionary:
one: 1
two: 2
number: 2
list:
- one
- two
- four
- name: John
age: 20
USERNAME:
type: env
load: USERNAME
callable_lambda:
type: lambda
load: "lambda: print('hell world!')"
datenow:
type: lambda
import:
- "from datetime import datetime as dd"
load: "lambda: print(dd.utcnow().strftime('%Y-%m-%d'))"
test_function:
type: function
name: test_function
args:
x: 7
y: null
s: hello world
any:
- 1
- hello
import:
- "math"
load: >
def test(x, y, s, any):
print(math.e)
iii = 111
print(iii)
print(x,s)
if y:
print(type(y))
else:
print(y)
for i in any:
print(i)
然后把它当作一个对象来使用。
>> from pickle_rick import PickleRick
>> config = PickleRick('./config.yaml', deep=True, load_lambda=True)
>> config.BASIC.dictionary
{'one' : 1, 'two' : 2}
>> config.BASIC.callable_lambda()
hell world!
您可以定义 Python 函数,从其他文件或 REST API、环境变量加载额外数据,然后将所有内容写入 YAML 或再次 JSON。
这在构建需要结构化配置文件的系统或在笔记本中作为交互式结构时特别有效。
使用它有一个安全说明。只加载受信任的文件,因为任何代码都可以执行,因此避免在不知道完整内容的情况下只加载任何内容。
该包名为 PickleRick,可在此处获取:
我有一个 .yml 配置文件,它根据我 运行 的客户端控制我的程序的所有文件 I/O。客户端名称应位于 YAML 文件中给出的路径中的某处,例如:
client: CLIENT_1
data:
raw-file-path: D://Users//product//data//raw//CLIENT_1//CLIENT_1_data.csv
processed-data-file-path: D://Users//product//data//processed//CLIENT_1//CLIENT_1_processed_data.csv
有多个客户端,它们的数据始终位于指定的子目录中。我的代码为每个客户端提取原始数据,并在适当的目录中生成处理后的数据,如上例所示。在大多数情况下,我想 运行 单个客户端的脚本,因此我可以编辑我显示的 config.yml
文件,但我希望能够以编程方式进行。我在 ArgumentParser 中添加了一个 --clients
参数:parser.add_argument('--clients', nargs='+', default=[], help='list of clients')
以允许将客户端列表作为输入给出,例如 python run.py --config config.yml --clients CLIENT_1 CLIENT_2
我想找到一种方法来操纵所有这些路径以指向适当的目录,甚至可以利用类似 f-strings 的东西命名文件,但我不知道该怎么做。我发现最接近的问题是这个问题:
有一个 Python 包可用于从 YAML/JSON/dicts 巧妙地构造对象,并且正在积极开发和扩展。 (完全公开,我是这个包的合著者,参见here)
此外,还有用于传递参数的选项,请参阅 this
然后你可以在 YAML 中定义它:
some_field: _|arg_name|_
并像这样加载它:
test_conf_yaml = PickleRick('./tests/placebos/test_config.yaml', arg_name='hallo world')
安装:
pip install pickle-rick
使用:
定义 YAML 或 JSON 字符串(或文件)。
BASIC:
text: test
dictionary:
one: 1
two: 2
number: 2
list:
- one
- two
- four
- name: John
age: 20
USERNAME:
type: env
load: USERNAME
callable_lambda:
type: lambda
load: "lambda: print('hell world!')"
datenow:
type: lambda
import:
- "from datetime import datetime as dd"
load: "lambda: print(dd.utcnow().strftime('%Y-%m-%d'))"
test_function:
type: function
name: test_function
args:
x: 7
y: null
s: hello world
any:
- 1
- hello
import:
- "math"
load: >
def test(x, y, s, any):
print(math.e)
iii = 111
print(iii)
print(x,s)
if y:
print(type(y))
else:
print(y)
for i in any:
print(i)
然后把它当作一个对象来使用。
>> from pickle_rick import PickleRick
>> config = PickleRick('./config.yaml', deep=True, load_lambda=True)
>> config.BASIC.dictionary
{'one' : 1, 'two' : 2}
>> config.BASIC.callable_lambda()
hell world!
您可以定义 Python 函数,从其他文件或 REST API、环境变量加载额外数据,然后将所有内容写入 YAML 或再次 JSON。
这在构建需要结构化配置文件的系统或在笔记本中作为交互式结构时特别有效。
使用它有一个安全说明。只加载受信任的文件,因为任何代码都可以执行,因此避免在不知道完整内容的情况下只加载任何内容。
该包名为 PickleRick,可在此处获取: