Python
Click

clickでカスタムの引数型を定義する(例: 文字列をevalしたものをオプションの値にする型の実装)

More than 1 year has passed since last update.

clickでは、カスタムの引数型を定義して使うことができます。
http://click.pocoo.org/6/parameters/#implementing-custom-types

方法

click.ParamType を継承したクラスを作り、convert() をオーバーライドします。
convert() が返す値がNoneの場合、default引数が設定されていればその値(をまたこのconvert()を通したもの)がオプションの値となります。

例) 文字列をevalしたものをオプションの値にする型

以下の実装例では、文字列以外はevalせずに返し、evalできない文字列は生のまま返しています。
空白を含むならクオートして渡します。シェルに展開されてしまう文字列はエスケープするなり工夫が必要です。

eval_param_type.py
# -*- encoding: utf-8 -*-
import click

class EvalParamType(click.ParamType):
    def convert(self, value, param, ctx):
        if not isinstance(value, str):
            return value
        try:
            return eval(value)
        except:
            return value  # raw string


@click.command()
@click.option('--p', type=EvalParamType(), default={0:1, 2:3})
## typeキーワードにはクラスのインスタンスを渡します
def main(**kwargs):
    if 'p' in kwargs:
        print 'kwargs:', kwargs
        p = kwargs['p']
        print p.__class__, p


if __name__ == '__main__':
    main()

試してみます

$ python eval_param_type.py 
kwargs: {'p': {0: 1, 2: 3}}
<type 'dict'> {0: 1, 2: 3}

$ python eval_param_type.py --p "Hello"
kwargs: {'p': 'Hello'}
<type 'str'> Hello

$ python eval_param_type.py --p "'Hello, world'"
kwargs: {'p': 'Hello, world'}
<type 'str'> Hello, world

$ python eval_param_type.py --p hello
kwargs: {'p': 'hello'}
<type 'str'> hello

$ python eval_param_type.py --p 3.14
kwargs: {'p': 3.14}
<type 'float'> 3.14

$ python eval_param_type.py --p 5
kwargs: {'p': 5}
<type 'int'> 5

$ python eval_param_type.py --p -3
kwargs: {'p': -3}
<type 'int'> -3

$ python eval_param_type.py --p True
kwargs: {'p': True}
<type 'bool'> True

$ python eval_param_type.py --p 1+2
kwargs: {'p': 3}
<type 'int'> 3

$ python eval_param_type.py --p []
kwargs: {'p': []}
<type 'list'> []

$ python eval_param_type.py --p "()"
kwargs: {'p': ()}
<type 'tuple'> ()

$ python eval_param_type.py --p None
kwargs: {'p': {0: 1, 2: 3}}
<type 'dict'> {0: 1, 2: 3}
// ’None’をevalするとNoneになって、default引数に設定された値を見に行く