使用python click,如何避免重复多个子命令使用的参数代码
我有一组子命令,所有子命令都对URL列表进行操作,这些URL可以选择作为参数传递。如何将此参数指定给组,以避免在每个子命令上重复参数定义 当前代码:使用python click,如何避免重复多个子命令使用的参数代码,python,command-line-interface,python-click,Python,Command Line Interface,Python Click,我有一组子命令,所有子命令都对URL列表进行操作,这些URL可以选择作为参数传递。如何将此参数指定给组,以避免在每个子命令上重复参数定义 当前代码: from config import site_list @click.group() def cli(): pass @cli.command() @cli.argument('sites', nargs=-1) def subcommand_one(): if sites: site_list = sites
from config import site_list
@click.group()
def cli():
pass
@cli.command()
@cli.argument('sites', nargs=-1)
def subcommand_one():
if sites:
site_list = sites
etc...
@cli.command()
@cli.argument('sites', nargs=-1)
def subcommand_two():
if sites:
site_list = sites
etc...
调用示例:
$ python sites.py subcommand_one www.example.com www.example2.com
我尝试将参数装饰器移动到组中,如下所示:
@click.group()
@click.argument('sites', nargs=-1)
def cli(sites):
if sites:
site_list = sites
但是我会得到这个错误:
$ python sites.py subcommand_one
Usage: sites.py [OPTIONS] [SITES] COMMAND [ARGS]...
Try "sites.py --help" for help.
Error: Missing command.
click.argument
与其他任何变量一样只返回一个decorator,因此您可以将其分配给某个变量:
import click
@click.group()
def cli():
pass
sites_argument = click.argument('sites', nargs=-1)
@cli.command()
@sites_argument
def subcommand_one(sites):
...
@cli.command()
@sites_argument
def subcommand_two(sites):
...
如果有一个特定的
nargs=-1
参数,您只想修饰到组中,但适用于
根据需要执行所有命令,您可以使用一些额外的管道来执行这些操作,如:
这个答案的灵感来源于答案
自定义类
使用自定义类:
要使用自定义类,请将cls
参数传递给click.group()
decorator,使用
@GroupNArgsForCommands.command_参数
特殊参数的装饰器,然后添加
与任何命令的特殊参数同名的参数
@click.group(cls=GroupNArgsForCommands)
@GroupNArgsForCommands.command_argument('special', nargs=-1)
def a_group():
"""My project description"""
@a_group.command()
def a_command(special):
"""a command under the group"""
这是怎么回事?
这是因为click
是一个设计良好的OO框架。@click.group()
装饰程序通常
实例化一个click.Group
对象,但允许使用cls
参数过度执行此行为。因此,在我们自己的类中继承
click.Group
并超越所需的方法是一件相对容易的事情
在本例中,我们将跳过单击.Group.add_command()
,以便在添加命令时可以进行检查
命令回调参数,查看它们是否与任何特殊参数同名。
如果它们匹配,参数将被添加到命令的参数中,就像它被直接修饰一样
此外,GroupNArgsForCommands
实现了一个command\u参数()
方法。此方法用作
添加特殊参数而不是使用click.argument()
测试班
结果:
我认为通过使用
@Click.pass\u上下文
,Click支持一个实际的解决方案
如果要定义一组命令,这些命令共享一个公共参数和一个公共选项,则可以在组级别上定义这些命令,并将它们添加到上下文对象中,如
@click.group(chain=True)
@click.argument(“数据集目录”,type=click.Path(exists=True))
@单击.option(“-s”,”--split name),help=“要预处理的拆分”,required=True,
默认值=[“列车集”、“devset”、“测试集”],显示(默认值=真)
@单击。传递上下文
def cli(ctx、数据集目录、拆分名称):
"""
为培训准备数据集
DATASET\u目录数据目录的绝对路径。
"""
ctx.确保对象(dict)
ctx.obj[“目录”]=数据集目录
ctx.obj[“拆分”]=拆分名称
然后,该组的各个命令可以通过上下文传递,并使用上下文对象中的值,而不是定义它们自己的参数和选项
@cli.命令(“创建”)
@单击。传递上下文
def创建(ctx):
从csv(ctx.obj[“DIRECTORY”]、ctx.obj[“SPLITS”])创建\u语义\u json\u
@cli.命令(“标记化”)
@单击。传递上下文
def标记化(ctx):
预处理\u标记化\u语义\u json(ctx.obj[“目录”]、ctx.obj[“拆分”])
然后可以调用以下命令:
my cli app/path/to/data create tokenize
我想使该参数成为可选参数并提供默认值,但当我尝试sites\u参数=click.argument('sites',nargs=-1,default=site\u list)时
我得到了这个错误TypeError:nargs=-1与默认值结合使用是不受支持的。
在这里分配默认值的最佳方法是什么?您可以没有默认值,在函数测试中使用空列表,也可以使用回调。这是我所问问题的最佳答案。然而,维亚坦的答案对我来说可能是一个更好的解决方案。我试图理解如何在他的解决方案中为参数提供默认值。
@click.group(cls=GroupNArgsForCommands)
@GroupNArgsForCommands.command_argument('special', nargs=-1)
def a_group():
"""My project description"""
@a_group.command()
def a_command(special):
"""a command under the group"""
import click
@click.group(cls=GroupNArgsForCommands)
@GroupNArgsForCommands.command_argument('sites', nargs=-1)
def cli():
click.echo("cli group")
@cli.command()
def command_one(sites):
click.echo("command_one: {}".format(sites))
@cli.group()
def subcommand():
click.echo("subcommand group")
@subcommand.command()
def one():
click.echo("subcommand_one")
@subcommand.command()
def two(sites):
click.echo("subcommand_two: {}".format(sites))
if __name__ == "__main__":
commands = (
'command_one site1 site2',
'command_one site1',
'command_one',
'subcommand',
'subcommand one site1 site2',
'subcommand one site1',
'subcommand one',
'subcommand two site1 site2',
'subcommand two site1',
'subcommand two',
'--help',
'command_one --help',
'subcommand --help',
'subcommand one --help',
'subcommand two --help',
'',
)
import sys, time
time.sleep(1)
print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
for command in commands:
try:
time.sleep(0.1)
print('-----------')
print('> ' + command)
time.sleep(0.1)
cli(command.split())
except BaseException as exc:
if str(exc) != '0' and \
not isinstance(exc, (click.ClickException, SystemExit)):
raise
Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> command_one site1 site2
cli group
command_one: ('site1', 'site2')
-----------
> command_one site1
cli group
command_one: ('site1',)
-----------
> command_one
cli group
command_one: ()
-----------
> subcommand
cli group
Usage: test.py subcommand [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
one
two
-----------
> subcommand one site1 site2
Usage: test.py subcommand one [OPTIONS]
Error: Got unexpected extra arguments (site1 site2)
cli group
subcommand group
-----------
> subcommand one site1
cli group
subcommand group
Usage: test.py subcommand one [OPTIONS]
Error: Got unexpected extra argument (site1)
-----------
> subcommand one
cli group
subcommand group
subcommand_one
-----------
> subcommand two site1 site2
cli group
subcommand group
subcommand_two: ('site1', 'site2')
-----------
> subcommand two site1
cli group
subcommand group
subcommand_two: ('site1',)
-----------
> subcommand two
cli group
subcommand group
subcommand_two: ()
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
command_one
subcommand
-----------
> command_one --help
cli group
Usage: test.py command_one [OPTIONS] [SITES]...
Options:
--help Show this message and exit.
-----------
> subcommand --help
cli group
Usage: test.py subcommand [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
one
two
-----------
> subcommand one --help
cli group
subcommand group
Usage: test.py subcommand one [OPTIONS]
Options:
--help Show this message and exit.
-----------
> subcommand two --help
cli group
subcommand group
Usage: test.py subcommand two [OPTIONS] [SITES]...
Options:
--help Show this message and exit.
-----------
>
Usage: test.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
command_one
subcommand