将许多 argparse 条件论证转换为更 Pythonic 的解决方案 [英] Convert many argparse conditional arguements to a more pythonic solution

查看:30
本文介绍了将许多 argparse 条件论证转换为更 Pythonic 的解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a cli application using python. I have a set of arguments that are mutually exclusive and a set of arguments that must be there if one of those mutually exclusive arguments is passed.
I have got it working using brute force and lengthy if conditions, but I feel like there is a neat way to do this. Researching about that told me subparsers might be useful, however I am not able to correctly use subparsers at all.
The conditions I want are the following-
Main activities
+-----+--------+--------+--------+---------+
| get | create | delete | update | remove |
+-----+--------+--------+--------+---------+

这些主要活动相互排斥.

如果指定了 get,则应该不要再有任何争论.
如果指定了 delete,则应该不要再有任何争论.
如果指定了 remove,则 -r强制.
如果指定了update,则-f 强制-cd可选.
如果指定了 create,则 -dma​​ndatory-m-f> 是 可选,其中 -m-f互斥.

If get is specified, then there should not be any more arguements.
If delete is specified then there should not be any more arguements.
If remove is specified then -r is mandatory.
If update is specified then -f mandatory, and-cd is optional.
If create is specified, then -d is mandatory, -m and -f are optional where -m and -f are mutually exclusive.

暴力破解代码如下-

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

有没有办法让它更像pythonic?

Is there any way to make it more pythonic ?

编辑 1:
为什么我没有使用 subparser 包含代码?
因为到目前为止我已经理解,子解析器本身不接受任何值.所以就我而言,我希望能够像这样执行脚本 -

EDIT 1:
Why have I not included code using subparser ?
Because so far I have understood, subparsers don't themselves take any values. So in my case I want to be able to execute the script like this -

  • prog -g xxy
  • prog -c xxyy -d 'Hello World'
  • prog -u xxyy -f 'file.md' -cd 'Foo bar baz'

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

Where as using subparsers, they would become something like (which I don't want, correct me if I am wrong)-

  • prog get -g xxy
  • prog create -c xxyy -d 'Hello World'

编辑 2
我想出了如何使用 add_mutually_exclusive_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
我无法进行 subparse 工作.以下代码(使用子集)抛出错误 error: invalid choice: 'world' (choose from '-m', '-f') 如果命令是 $ python3 parse2.py -c hello -m world

EDIT 3
I am not able to get the subparse work. The following code (working with a subset) throws the error error: invalid choice: 'world' (choose from '-m', '-f') if the command is $ python3 parse2.py -c hello -m world

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
我几乎用以下方法解决了我的问题 -

EDIT 4
I have almost solved my issue with the following -

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)

但是我想知道是否可以为 getdeletecreate 添加 add_mutually_exclusive_groupupdateremove 还是我必须使用 if 条件来执行此操作?

However I want to know if it is possible to add the add_mutually_exclusive_group for get, delete, create, update and remove or do I have to do that using if conditions?

推荐答案

子解析器版本的开始:

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

这篇关于将许多 argparse 条件论证转换为更 Pythonic 的解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆