使argsparse subparsers可选

时间:2016-12-22 09:43:31

标签: python

所以我有以下代码:

parser = argparse.ArgumentParser(description='Manages anime_list.json', add_help=True, version='0.1')
parser.add_argument('-l', '--list', action='store_true', help='List all anime in file')

subparser = parser.add_subparsers(title='Actions', description='Actions that can be performed', dest='command')

add = subparser.add_parser('=add', help='Add anime entry')
add.add_argument('-n', '--name', type=str, required=False, default='',
                 help='The name of the anime adding. Will be auto filled in if left blank')
add.add_argument('-e', '--episode', type=int, required=False, default=0,
                 help='The last watched episode. Download starts add +1 this episode')
add.add_argument('-u', '--url', type=str, required=True, help='A link to any episode for the anime')

remove = subparser.add_parser('=remove', help='Remove anime entry')
remove.add_argument('-n', '--name', type=str, required=True, default='',
                    help='The name of the anime to remove')

args = parser.parse_args()

我想要的是subparsers是可选的。当用户使用--list参数时,不必提供subparsers参数。使用argsparse的-h-v选项时,解析完成,并显示帮助信息或版本号。但是当只使用我自己的-l时,它会抛出一个异常,说明没有提供足够的参数。

我发现一条建议说使用subparser.required = False会使它们成为可选项,但它不起作用。

知道我怎么能这样做吗?我已经看了这个,似乎无法找到解决方案。

3 个答案:

答案 0 :(得分:0)

所以我找到了一个解决方案,在我看来并不是最优的,但它确实有效。

感谢Matthew在this answer

修改如下代码可以获得我想要的功能。

parser = argparse.ArgumentParser(description='Manages anime_list.json', add_help=True, version='0.1')
parser.add_argument('-l', '--list', action='store_true', help='List all anime in file')    

args, sub_commands = parser.parse_known_args()

if args.list:
    print 'Doing list'
else:
    subparser = parser.add_subparsers(title='Actions', description='Actions that can be performed', dest='command')

    add = subparser.add_parser('=add', help='Add anime entry')
    add.add_argument('-n', '--name', type=str, required=False, default='',
                     help='The name of the anime adding. Will be auto filled in if left blank')
    add.add_argument('-e', '--episode', type=int, required=False, default=0,
                     help='The last watched episode. Download starts add +1 this episode')
    add.add_argument('-u', '--url', type=str, required=True, help='A link to any episode for the anime')

    remove = subparser.add_parser('=remove', help='Remove anime entry')
    remove.add_argument('-n', '--name', type=str, required=True, default='',
                        help='The name of the anime to remove')

    args = parser.parse_args()
    print args

return args

基本上解析已知的参数,在这种情况下它将是-l。如果未提供-l参数,请添加所需的子分析程序并再次解析参数。

如果以这种方式完成,您的--help将不再有效,因为它不会显示子分析符'帮助文本。您必须创建手动帮助功能。

答案 1 :(得分:0)

投入default参数。例如:

parser.add_argument('-l', '--list', action='store_true', help='List all anime in file', default=False)    

这将存储默认值False,并且仅当提供-l标志时,列表变量才为True

答案 2 :(得分:0)

我使用以下解决方案,发现它很干净,它可以帮助我扩展命令行程序并使其更加具体。

1)用父级和子级解析器定义一个主要的通用和标准argparse。我是在主库或在相似但不同的项目中使用的通用类中完成此操作的。

2)添加一个子解析器以逃避通用的argparse,诸如“ other”之类的东西。

3)在特定的应用程序中,创建第二个argparser,该参数在第一个参数为“其他”时使用。

示例: 假设我要始终使用/继承一些常见的子解析器和父级,然后再添加一些特定于应用程序的解析器。假设标准的通用解析器具有以下子解析器:load,query,show,...,other。

然后它将与:

python code.py加载-arg1 -arg2 ...

python code.py show -arga -argb ...

同时,当使用“ other”时,它将使用父args,而不执行任何操作,因此可以使用其他特定于案例的解析器。

python code.py其他application_specific_command -arg3 -arg4

显然,这不会使子解析器成为可选内容,因此这不是直接的答案;更多在某些情况下可行的替代方案。我认为它具有一些优点:

1)没有很多if或try的逻辑实现2)可以将父args传递给特定于应用程序的解析器(如果“ other”具有父级)3)允许“ other”使用一些通用的args,即针对所有特定情况的命令4)维护args帮助