Python 单击 - 从配置文件提供参数和选项
Python Click - Supply arguments and options from a configuration file
给定以下程序:
#!/usr/bin/env python
import click
@click.command()
@click.argument("arg")
@click.option("--opt")
@click.option("--config_file", type=click.Path())
def main(arg, opt, config_file):
print("arg: {}".format(arg))
print("opt: {}".format(opt))
print("config_file: {}".format(config_file))
return
if __name__ == "__main__":
main()
我可以 运行 使用命令行提供的参数和选项。
$ ./click_test.py my_arg --config_file my_config_file
arg: my_arg
opt: None
config_file: my_config_file
如何向 --config_file
提供配置文件(在 ini
?yaml
?py
?json
?)并接受内容作为参数和选项的值?
例如,我希望 my_config_file
包含
opt: my_opt
并显示程序的输出:
$ ./click_test.py my_arg --config_file my_config_file
arg: my_arg
opt: my_opt
config_file: my_config_file
我发现 callback
函数看起来很有用,但我找不到将同级函数 arguments/options 修改为相同函数的方法。
这可以通过覆盖 click.Command.invoke()
方法来完成,例如:
自定义 Class:
def CommandWithConfigFile(config_file_param_name):
class CustomCommandClass(click.Command):
def invoke(self, ctx):
config_file = ctx.params[config_file_param_name]
if config_file is not None:
with open(config_file) as f:
config_data = yaml.safe_load(f)
for param, value in ctx.params.items():
if value is None and param in config_data:
ctx.params[param] = config_data[param]
return super(CustomCommandClass, self).invoke(ctx)
return CustomCommandClass
使用自定义 Class:
然后使用自定义 class,将其作为 cls 参数传递给命令装饰器,如:
@click.command(cls=CommandWithConfigFile('config_file'))
@click.argument("arg")
@click.option("--opt")
@click.option("--config_file", type=click.Path())
def main(arg, opt, config_file):
测试代码:
# !/usr/bin/env python
import click
import yaml
@click.command(cls=CommandWithConfigFile('config_file'))
@click.argument("arg")
@click.option("--opt")
@click.option("--config_file", type=click.Path())
def main(arg, opt, config_file):
print("arg: {}".format(arg))
print("opt: {}".format(opt))
print("config_file: {}".format(config_file))
main('my_arg --config_file config_file'.split())
测试结果:
arg: my_arg
opt: my_opt
config_file: config_file
给定以下程序:
#!/usr/bin/env python
import click
@click.command()
@click.argument("arg")
@click.option("--opt")
@click.option("--config_file", type=click.Path())
def main(arg, opt, config_file):
print("arg: {}".format(arg))
print("opt: {}".format(opt))
print("config_file: {}".format(config_file))
return
if __name__ == "__main__":
main()
我可以 运行 使用命令行提供的参数和选项。
$ ./click_test.py my_arg --config_file my_config_file
arg: my_arg
opt: None
config_file: my_config_file
如何向 --config_file
提供配置文件(在 ini
?yaml
?py
?json
?)并接受内容作为参数和选项的值?
例如,我希望 my_config_file
包含
opt: my_opt
并显示程序的输出:
$ ./click_test.py my_arg --config_file my_config_file
arg: my_arg
opt: my_opt
config_file: my_config_file
我发现 callback
函数看起来很有用,但我找不到将同级函数 arguments/options 修改为相同函数的方法。
这可以通过覆盖 click.Command.invoke()
方法来完成,例如:
自定义 Class:
def CommandWithConfigFile(config_file_param_name):
class CustomCommandClass(click.Command):
def invoke(self, ctx):
config_file = ctx.params[config_file_param_name]
if config_file is not None:
with open(config_file) as f:
config_data = yaml.safe_load(f)
for param, value in ctx.params.items():
if value is None and param in config_data:
ctx.params[param] = config_data[param]
return super(CustomCommandClass, self).invoke(ctx)
return CustomCommandClass
使用自定义 Class:
然后使用自定义 class,将其作为 cls 参数传递给命令装饰器,如:
@click.command(cls=CommandWithConfigFile('config_file'))
@click.argument("arg")
@click.option("--opt")
@click.option("--config_file", type=click.Path())
def main(arg, opt, config_file):
测试代码:
# !/usr/bin/env python
import click
import yaml
@click.command(cls=CommandWithConfigFile('config_file'))
@click.argument("arg")
@click.option("--opt")
@click.option("--config_file", type=click.Path())
def main(arg, opt, config_file):
print("arg: {}".format(arg))
print("opt: {}".format(opt))
print("config_file: {}".format(config_file))
main('my_arg --config_file config_file'.split())
测试结果:
arg: my_arg
opt: my_opt
config_file: config_file