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引数に設定された値を見に行く