将许多argparse条件论据转换为更pythonic的解决方案

时间:2018-11-14 19:42:36

标签: python arguments command-line-interface argparse

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

这些主要活动是相互排斥的

如果指定了 get ,则应该不再发生争论。
如果指定了删除,则应该不再。 如果指定了删除,则-r强制
如果指定了更新,则-f 强制,并且-cd可选
如果指定了 create ,则-d强制-m-f可选,其中{ {1}}和-m互斥的

蛮力代码如下-

-f

有什么办法可以使其更具pythonic性?

编辑1:
为什么我没有包含使用 subparser 的代码?
因为到目前为止,我了解到,劣质者本身并没有任何价值。因此,就我而言,我希望能够执行这样的脚本-

  • 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')
  • prog -g xxyy
  • prog -c xxyy -d 'Hello World'

在使用子解析器的情况下,它们将变成类似(我不想要的,如果我错了的话请纠正我)-

  • prog -u xxyy -f 'file.md' -cd 'Foo bar baz'
  • prog get -g xxyy

编辑2
我想出了如何使用prog create -c xxyy -d 'Hello World'

进行相互排斥的争论
add_mutually_exclusive_group

编辑3
我无法获得 subparse 的工作。如果命令为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')

,以下代码(使用子集)将引发错误error: invalid choice: 'world' (choose from '-m', '-f')
$ python3 parse2.py -c hello -m world

编辑4
我几乎可以通过以下方法解决我的问题-

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)

但是我想知道是否可以为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) add_mutually_exclusive_groupgetdeletecreate添加update还是我必须使用remove条件来做到这一点?

1 个答案:

答案 0 :(得分:1)

子解析器版本的开始:

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')