如果通过使用自定义选项类将列表格式化为python列表的字符串文字,则可以强制单击以获取多个列表参数:
自定义类:
import click
import ast
class PythonLiteralOption(click.Option):
def type_cast_value(self, ctx, value):
try:
return ast.literal_eval(value)
except:
raise click.BadParameter(value)
该类将使用Python的Abstract Syntax Tree模块将参数解析为python文字.
自定义类用法:
要使用自定义类,请将cls参数传递给@ click.option()装饰器,如:
@click.option('--option1', cls=PythonLiteralOption, default=[])
这是如何运作的?
这是有效的,因为click是一个设计良好的OO框架. @ click.option()装饰器通常实例化click.Option对象,但允许使用cls参数覆盖此行为.因此,从我们自己的类中继承click.Option并过度使用所需的方法是一个相对容易的事情.
在这种情况下,我们遍历click.Option.type_cast_value()然后调用ast.literal_eval()来解析列表.
测试代码:
@click.command(context_settings=dict(help_option_names=['-h', '--help']))
@click.option('--option1', cls=PythonLiteralOption, default=[])
@click.option('--option2', cls=PythonLiteralOption, default=[])
def cli(option1, option2):
click.echo("Option 1, type: {} value: {}".format(
type(option1), option1))
click.echo("Option 2, type: {} value: {}".format(
type(option2), option2))
# do stuff
if __name__ == '__main__':
import shlex
cli(shlex.split(
'''--option1 '["o11", "o12", "o13"]'
--option2 '["o21", "o22", "o23"]' '''))
检测结果:
Option 1, type: value: ['o11', 'o12', 'o13']
Option 2, type: value: ['o21', 'o22', 'o23']