将许多argparse条件参数转换为更具Python风格的解决方案

将许多argparse条件参数转换为更具Python风格的解决方案,python,arguments,command-line-interface,argparse,Python,Arguments,Command Line Interface,Argparse,我正在使用python开发一个cli应用程序。我有一组互斥的参数,如果传递了其中一个互斥的参数,则必须有一组参数。 我用蛮力和冗长的if条件让它工作,但我觉得有一种巧妙的方法可以做到这一点。对此进行的研究告诉我,subparser可能有用,但我根本无法正确使用subparser。 我想要的条件如下- 主要活动 +-----+--------+--------+--------+---------+ |获取|创建|删除|更新|删除| +-----+--------+--------+-------

我正在使用python开发一个cli应用程序。我有一组互斥的参数,如果传递了其中一个互斥的参数,则必须有一组参数。
我用蛮力和冗长的
if
条件让它工作,但我觉得有一种巧妙的方法可以做到这一点。对此进行的研究告诉我,subparser可能有用,但我根本无法正确使用subparser。
我想要的条件如下-
主要活动
+-----+--------+--------+--------+---------+
|获取|创建|删除|更新|删除|
+-----+--------+--------+--------+---------+

这些主要活动相互排斥

如果指定了get则应有不应更多参数。
如果指定了delete,则应不再有任何争论。
如果指定了删除,则
-r
必需的
如果指定了更新,则
-f
必须,而
-cd
可选
如果指定了create,则
-d
必需的
-m
-f
可选的,其中
-m
-f
互斥的

暴力代码如下所示-

import argparse
parser = argparse.ArgumentParser(description='Check args')
#get
parser.add_argument('-g', '--get', help='')
#create
parser.add_argument('-c', '--create', help='')
parser.add_argument('-d', '--display', help='')
parser.add_argument('-m', '--message', help='')
parser.add_argument('-f', '--file', help='')
#update
parser.add_argument('-u', '--update', help='')
parser.add_argument('-cd', '--changed', help='')
#delete
parser.add_argument('-del', '--delete', help='')
#remove
parser.add_argument('-rm', help='')
parser.add_argument('-r', '--remove', help='')

args = vars(parser.parse_args())

if args['get'] is not None:
    if args['create'] is None and args['display'] is None and args['message'] is None and args['file'] is None and args['update'] is None and args['changed'] is None and args['delete'] is None and args['rm'] is None and args['remove'] is None:
        print(args['get'])
    else:
        print('Dont mix get with others')
        exit()

if args['create']:
    if args['get'] is None and args['message'] is None and args['file'] is None and args['update'] is None and args['changed'] is None and args['delete'] is None and args['rm'] is None and args['remove'] is None:
        print(args['create'])
    else:
        print('Dont mix create with others')
        exit()
    if args['display'] is None:
        print('Missing display')

if args['update']:
    if args['get'] is None and args['create'] is None and args['display'] is None and args['message'] is None and args['delete'] is None and args['rm'] is None and args['remove'] is None:
        print(args['update'])
    else:
        print('Dont mix update with others')
        exit()
    if args['file'] is None:
        print('Missing file')

if args['delete']:
    if args['get'] is None and args['create'] is None and args['display'] is None and args['message'] is None and args['file'] is None and args['update'] is None and args['changed'] is None and args['rm'] is None and args['remove'] is None:
        print(args['delete'])
    else:
        print('Dont mix delete with others')
        exit()

if args['rm']:
    if args['get'] is None and args['create'] is None and args['display'] is None and args['message'] is None and args['file'] is None and args['update'] is None and args['changed'] is None and args['delete'] is None:
        print(args['rm'])
    else:
        print('Dont mix resource management with others')
        exit()
    if args['remove'] is None:
        print('Missing remove')
有没有办法让它更像蟒蛇

编辑1:
为什么我没有包含使用subparser的代码?
因为到目前为止我已经了解到,次级帕斯人自己并不接受任何价值观。所以在我的例子中,我希望能够像这样执行脚本-

  • prog-g xxyy
  • prog-cxxyy-d“你好,世界”
  • prog-u xxyy-f'file.md'-cd'Foo-bar-baz'
在使用subparser时,它们会变成这样(我不希望,如果我错了,请纠正我)-

  • prog get-g xxyy
  • prog create-c xxyy-d'Hello World'
编辑2
我用
add\u mutual\u exclusive\u group

parser = argparse.ArgumentParser(description='Mutex')
group = parser.add_mutually_exclusive_group()
group.add_argument('-g')
group.add_argument('-c')
group.add_argument('-u')
group.add_argument('-del')
group.add_argument('-rm')
编辑3
我没办法得到那份差劲的工作。以下代码(使用子集)抛出错误
错误:如果命令是
$python3 parse2.py-c hello-m world,则选项无效:“world”(从'-m','-f')

parser = argparse.ArgumentParser(description='Mutex')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-g')
group.add_argument('-c')
subparser = parser.add_subparsers()
parser_a = subparser.add_parser('-m')
parser_b = subparser.add_parser('-f')
args = parser.parse_args()
print(args)
编辑4
我几乎解决了以下问题:

import argparse
parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='main') # , required=True) in Py3.7
sp.required = True    # in py 3.6
p1 = sp.add_parser('get')
p1.add_argument('id')

p2 = sp.add_parser('update')
p2.add_argument('id')
p2.add_argument('-f', required=True)
p2.add_argument('-cd')

p3 = sp.add_parser('create')
p3.add_argument('name')
p3.add_argument('-d', required=True)
p3_mutex = p3.add_mutually_exclusive_group()
p3_mutex.add_argument('-f')
p3_mutex.add_argument('-m')

p4 = sp.add_parser('delete')
p4.add_argument('id')

p5 = sp.add_parser('remove')
p5.add_argument('id')
p5.add_argument('-r', required=True)

args = parser.parse_args()
print(args)

但是,我想知道是否可以为
get
delete
create
update
remove
添加
互斥组
,或者我是否必须使用
if
条件来执行此操作?

子帕瑟版本的开始:

import argparse
parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='main') # , required=True) in Py3.7
sp.required = True    # in py 3.6
p1 = sp.add_parser('get')
p1.add_argument('xxyy')

p2 = sp.add_parser('update')
p2.add_argument('xxyy')
p2.add_argument('-r', required=True)
p2.add_argument('--cd')
# and so forth
args = parser.parse_args()
print(args)
样本运行

0914:~/mypy$ python3 stack53307678.py -h
usage: stack53307678.py [-h] {get,update} ...

positional arguments:
  {get,update}

optional arguments:
  -h, --help    show this help message and exit
0914:~/mypy$ python3 stack53307678.py get abc
Namespace(main='get', xxyy='abc')
0914:~/mypy$ python3 stack53307678.py update abc -r foo --cd x
Namespace(cd='x', main='update', r='foo', xxyy='abc')

让我们看看你用潜艇做了什么。只需将您的描述转换为相应的
add_子parser
add_解析器
add_参数
调用。拟合应该是直截了当的。@hpaulj subparser的挑战是,它们本身不接受任何值,它们内部的解析器会接受。那是我的停车点。例如,在我的例子中,我希望能够像这样执行-
prog-gxxyy
prog-cxxyy-d'Hello World'
prog-rm xxyy-r'file.md'
。但是使用subparser,它们会变成类似于
prog get-gxxyy
的东西,为什么不“get xxyy”和“create xxyy-d2”呢。不管怎样,如果你不喜欢subparser,那么你需要做你自己的测试,找出一种方法告诉你的用户这些限制。我在一个bug问题中探讨了添加“inclusive”和其他分组。做测试还不错,但是用户界面太繁重了。@hpaulj实际上我对
prog get xxyy
prog create xxyy-d'xxzz'
很满意。事实上,我对此表示欢迎。下级警察允许你这么做吗?我已经形成了这样一种观点,即如果子parser get不接受任何值,那么我们必须在get like
prog get-g'xxyy'
之后再次添加a-g。但从您的评论来看,子parser似乎允许接受值。你有这样的例子吗?这几乎帮我解决了我的问题。我添加了一个edit4,它显示了我在前面的文章中提到的代码。我现在只想知道我是否必须使用
if
条件来确保
get
create
update
remove
delete
不一起使用,或者是否可以在顶部添加另一个
互斥组来实现这一点?我试图在顶部集成
add_mutual_exclusive_group
,但不知道如何集成。