How to make at least one argument required and have the possibility to take all arguments with argparse in Python?

吃可爱长大的小学妹 提交于 2020-01-16 18:42:07

问题


The program has 2 arguments to deal with: state and key. I need to have a possibility to give as input the following options:

  • prog -state state_value
  • prog -key key_value
  • prog -state state_value -key key_value

The closest thing is using mutually excluding groups, but it unables the possibility to give both arguments as input at once.


回答1:


I think this is beyond the abilities of argparse. You could perform a simple validation on the returned namespace afterwards though. You should include in your help that at least once of state or key is required.

def validate(namespace, parser):
    if not any(arg in {"state", "key"} for arg in vars(namespace).keys()):
        parser.print_help()
        parser.exit(2)

namespace = parser.parse_args()
validate(namespace, parser)



回答2:


As noted in https://stackoverflow.com/a/24911007/901925 there isn't a built in mechanism for testing this, but it is easy to make such a test after parsing. Assuming the arguments have the default default of None, such a test could be:

if args.state is None and args.key is None:
    parser.error('At least one of the arguments is required ')

Eventually argparse might have such a mechanism. There is a bug request for more testing power in groups, http://bugs.python.org/issue11588

One idea is to add UsageGroups, modeled on mutually exclusive groups, but with more general logic. The code isn't available for download, but I'd be interested in hearing whether this example is clear.

parser = argparse.ArgumentParser(prog='prog')
group = parser.add_usage_group(kind='any', required=True)
group.add_argument('-s', '--state', metavar='state_value')
group.add_argument('-k', '--key', metavar='key_value')
args = parser.parse_args()
print(args)

with an error message:

usage: prog [-h] (-s state_value | -k key_value)
prog: error: group any(): some of the arguments [state, key] is required

An alternative in the usage line is (-s state_value, -k key_value), since | is already being used for the mutually exclusive xor relation. The usage and error message could be customized.




回答3:


#!/usr/bin/python
#-*- coding:utf-8 -*-

import sys

paras = sys.argv.pop(0)
state_value = None
key_value = None
i=0
while i < len(paras):
    if paras[i] == '-state':
        state_value = paras[i]
    elif paras[i] == '-key':
        key_value = paras[i]
    i += 2

if state_value:
    # do something
    pass
if key_value:
    # do something
    pass


来源:https://stackoverflow.com/questions/24906478/how-to-make-at-least-one-argument-required-and-have-the-possibility-to-take-all

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!