web-dev-qa-db-ja.com

Pythonクリック-構成ファイルから引数とオプションを指定する

次のプログラムがあるとします。

#!/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

iniyamlpyjson?内の構成ファイルを--config_fileと引数とオプションの値としてコンテンツを受け入れますか?

たとえば、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関数を見つけましたが、同じ関数の兄弟引数/オプションを変更する方法が見つかりませんでした。

11
Calvin

これは、次のようにclick.Command.invoke()メソッドに乗って行うことができます。

カスタムクラス:

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

カスタムクラスの使用:

次に、カスタムクラスを使用するには、次のようにコマンドデコレータに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
25
Stephen Rauch