【问题标题】:Argparse required options with variable parameters?argparse 需要带有可变参数的选项?
【发布时间】:2019-07-08 07:57:38
【问题描述】:

我正在编写的程序需要 3 个输入中的 1 个。

2 个输入需要一个附加参数。其中 1 个输入需要 2 个附加参数。一次只能输入其中的一项。

如何使用argparse 模块确保这一点?

请参阅下面的代码了解我目前尝试过的内容。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-d',  
      default='temp.file')

parser.add_argument('command',
      choices=['g', 's', 'm'])

args = parser.parse_args()
>>> prog.py g #  requires 1 param.
>>> prog.py s #  requires 1 param.
>>> prog.py m #  requires 2 params.

【问题讨论】:

  • 不使用 argparse 如何读取接下来的 2 个参数?

标签: python python-3.x argparse


【解决方案1】:

gsm是子命令,可以使用子解析器来实现。

p = ArgumentParser()
p.add_argument('-d', default='temp.file')

subparsers = p.add_subparsers()
g_parser = subparsers.add_parser('g')
g_parser.add_argument('g_foo')

s_parser = subparsers.add_parser('s')
s_parser.add_argument('s_foo')

m_parser = subparsers.add_parser('m')
m_parser.add_argument('m_foo')
m_parser.add_argument('m_bar')

当您致电 p.parse_args 时,然后是 g_foo 等。只有在使用适当的子命令时才会出现在结果中。例如:

>>> p.parse_args(['g', '3'])
Namespace(d='temp.file', g_foo='3')
>>> p.parse_args(['m', '4', '5'])
Namespace(d='temp.file', m_foo='4', m_bar='5')

【讨论】:

    【解决方案2】:

    看起来对互斥组很有用

    import argparse
    
    parser = argparse.ArgumentParser()
    
    parser.add_argument('-d',  
          default='temp.file')
    mx = parser.add_mutually_exclusive_group(required=True)
    mx.add_argument('-g')
    mx.add_argument('-s')
    mx.add_argument('-m', nargs=2)
    
    args = parser.parse_args()
    print(args)
    

    示例运行:

    1316:~/mypy$ python3 stack56926264.py -h
    usage: stack56926264.py [-h] [-d D] (-g G | -s S | -m M M)
    
    optional arguments:
      -h, --help  show this help message and exit
      -d D
      -g G
      -s S
      -m M M
    
    1527:~/mypy$ python3 stack56926264.py -g foo
    Namespace(d='temp.file', g='foo', m=None, s=None)
    
    1528:~/mypy$ python3 stack56926264.py -s bar
    Namespace(d='temp.file', g=None, m=None, s='bar')
    
    1528:~/mypy$ python3 stack56926264.py -m 1 2
    Namespace(d='temp.file', g=None, m=['1', '2'], s=None)
    

    并发现一些错误:

    1528:~/mypy$ python3 stack56926264.py -m 1 2 -s bar -d afile
    usage: stack56926264.py [-h] [-d D] (-g G | -s S | -m M M)
    stack56926264.py: error: argument -s: not allowed with argument -m
    
    1528:~/mypy$ python3 stack56926264.py -m 1 
    usage: stack56926264.py [-h] [-d D] (-g G | -s S | -m M M)
    stack56926264.py: error: argument -m: expected 2 arguments
    
    1530:~/mypy$ python3 stack56926264.py -d afile
    usage: stack56926264.py [-h] [-d D] (-g G | -s S | -m M M)
    stack56926264.py: error: one of the arguments -g -s -m is required
    

    【讨论】:

      【解决方案3】:

      您可以自己检查参数是否符合您的逻辑:

      parser = argparse.ArgumentParser()
      
      parser.add_argument('-d',  
                          default='temp.file')
      
      parser.add_argument('command',
                          choices=['g', 's', 'm'])
      
      parser.add_argument('additionals',
                          nargs='+')
      
      args = parser.parse_args()
      
      if args.command in ('g', 's') and len(args.additionals) != 1:
          print("Commands g and s require 1 argument")
      elif args.command == 'm' and len(args.additionals) != 2:
          print("Command m require 2 arguments")
      

      解决此问题的另一种方法是将这些命令分隔为不同的参数,并使用它们所需的相应数量的附加参数:

      parser = argparse.ArgumentParser()
      
      parser.add_argument('-d',  
                          default='temp.file')
      
      parser.add_argument('-g',
                          nargs=1)
      
      parser.add_argument('-s',
                          nargs=1)
      
      parser.add_argument('-m',
                          nargs=2)
      
      args = parser.parse_args()
      

      阅读nargs,了解如何为一个操作使用多个参数。

      【讨论】:

      • 谢谢 Tomerikoo,在我的例子中,一次只能指定一个参数。
      • 在这种情况下@KevinSwindon 您可以使用第一个选项,并且您将在additionals 中以列表形式获得额外的参数。
      • 我选择了这个选项,因为它是最简单和最直接的。我按照您的建议调用 parser.parse_args() 后检查参数,这非常有效。谢谢 Tomerikoo,非常感谢!
      猜你喜欢
      • 2020-03-16
      • 1970-01-01
      • 2020-08-24
      • 2018-08-11
      • 1970-01-01
      • 2020-05-04
      • 2020-07-01
      • 2014-08-02
      • 1970-01-01
      相关资源
      最近更新 更多