【问题标题】:How to make at least one argument required and have the possibility to take all arguments with argparse in Python?如何至少需要一个参数并有可能在 Python 中使用 argparse 获取所有参数?
【发布时间】:2018-01-04 17:38:36
【问题描述】:

该程序有 2 个参数需要处理:状态和密钥。 我需要有可能提供以下选项作为输入:

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

最接近的是使用互斥组,但它无法给出 两个参数同时作为输入。

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    正如https://stackoverflow.com/a/24911007/901925 中所述,没有内置的机制来测试这个,但是在解析后很容易进行这样的测试。假设参数有默认的defaultNone,这样的测试可能是:

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

    最终argparse 可能会有这样的机制。有一个BUG请求更多的分组测试能力,http://bugs.python.org/issue11588

    一个想法是添加 UsageGroups,以互斥组为模型,但具有更一般的逻辑。该代码无法下载,但我很想知道这个示例是否清晰。

    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)
    

    带有错误消息:

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

    用法行中的替代方法是(-s state_value, -k key_value),因为| 已经被用于互斥的xor 关系。 usage 和错误信息可以自定义。

    【讨论】:

      【解决方案2】:

      我认为这超出了 argparse 的能力。不过,您可以在之后对返回的命名空间执行简单的验证。您应该在帮助中包含至少需要一次状态或密钥。

      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)
      

      【讨论】:

      • 除非您使用 SUPPRESS,否则每个参数都将出现在 namespace 中,至少具有其默认值(例如 None)。所以测试keys 的存在是行不通的。
      【解决方案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
      

      【讨论】:

      • 它不适用于当前情况。 “状态”和“键”可以采用多种值,用户根据需要将它们作为输入提供。帮助信息就在那里,唯一的问题是让程序至少使用 1 个值或两者兼而有之。
      • 好的,下次把你的代码弄清楚就好了。我已经更新了我的答案。
      猜你喜欢
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-05
      • 2019-02-04
      • 2012-06-24
      相关资源
      最近更新 更多