如何显示可选和条件参数的自定义错误消息

如何解决如何显示可选和条件参数的自定义错误消息

我正在尝试在 Python 脚本中实现一个有条件和可选的命令行参数。因此,有效的用法将如下所示,其中“-a”是可选的,“-b”是可选的,但只有在指定了“-a”时才有效。

[-a argumentA [-b argumentB]]

我有一个使用 argparse 执行此操作的解决方案,但我无法获得帮助和错误文本来执行我想要的操作。这是我的解决方案:

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("-a","--AAA",dest="aaa_arg",help="this is the 'a' argument")

namespace,extra = parser.parse_kNown_args()
if namespace.aaa_arg != None:
    parser.add_argument("-b","--BBB",dest="bbb_arg",help="only use 'b' when 'a' is used")

myArgs = parser.parse_args()

if myArgs.aaa_arg != None:
    print("AAA: " + myArgs.aaa_arg)
    if myArgs.bbb_arg != None:
        print("BBB: " + myArgs.bbb_arg)

命令行中各种参数的输出为:

>py test.py

>py test.py -a something
AAA: something

>py test.py -a something -b somethingElse
AAA: something
BBB: somethingElse

>py test.py -b somethingElse
usage: test.py [-h] [-a AAA_ARG]
test.py: error: unrecognized arguments: -b somethingElse

>py test.py -h
usage: test.py [-h] [-a AAA_ARG]

optional arguments:
  -h,--help                   show this help message and exit
  -a AAA_ARG,--AAA AAA_ARG    this is the 'a' argument

>

问题是,被告知“-b”是有效参数的用户会被错误消息“-b somethingElse”无法识别而感到困惑。如果该用户随后显示帮助,他们将不会看到列出的“-b”。

修复帮助相当简单。下面的第二个版本在 ArgumentParser 中使用了 conflict_handler 来允许自定义帮助消息。

import argparse

parser = argparse.ArgumentParser(conflict_handler="resolve")
parser.add_argument("-h","--help",action="store_true",dest="display_help")

parser.add_argument("-a",help="only use 'b' when 'a' is used")

myArgs = parser.parse_args()

if myArgs.display_help:
    print('''usage: test2.py [-h] [-a AAA_ARG [-b BBB_ARG]]

optional arguments:
  -h,--AAA AAA_ARG    this is the 'a' argument
  -b BBB_ARG,--BBB BBB_ARG    only use 'b' when 'a' is used''')
else:    
    if myArgs.aaa_arg != None:
        print("AAA: " + myArgs.aaa_arg)
        if myArgs.bbb_arg != None:
            print("BBB: " + myArgs.bbb_arg)

正如您在下面的输出中看到的,帮助消息将“-b”列为有效参数;但是,错误消息仍然指出“-b somethingElse”无法识别。

>py test2.py

>py test2.py -a something
AAA: something

>py test2.py -a something -b somethingElse
AAA: something
BBB: somethingElse

>py test2.py -b somethingElse
usage: test2.py [-h] [-a AAA_ARG]
test2.py: error: unrecognized arguments: -b somethingElse

>py test2.py -h
usage: test2.py [-h] [-a AAA_ARG [-b BBB_ARG]]

optional arguments:
  -h,--BBB BBB_ARG    only use 'b' when 'a' is used

>

我真正想要的是类似于下面显示输出(作为示例,此输出是手动创建的,而不是由 Python 创建):

>py test3.py

>py test3.py -a something
AAA: something

>py test3.py -a something -b somethingElse
AAA: something
BBB: somethingElse

>py test3.py -b somethingElse
usage: test2.py [-h] [-a AAA_ARG [-b BBB_ARG]]
test2.py: only use 'b' when 'a' is used

>py test3.py -h
usage: test2.py [-h] [-a AAA_ARG [-b BBB_ARG]]

optional arguments:
  -h,--BBB BBB_ARG    only use 'b' when 'a' is used

>

有没有办法自定义“-b”选项的错误信息?

更新:

根据@hpaulj 的建议,我将解析和条件检查分开了。该解决方案将“-a”和“-b”参数添加到解析器,然后检查条件并设置错误消息。

自定义用法消息添加到 ArgumentParser 并通过参数上的元变量属性调整帮助显示的参数名称匹配 uasge 语句和帮助消息中的参数描述。 最终结果比我开始时更简单:不需要解析两次,也不需要自定义帮助消息。

import argparse

parser = argparse.ArgumentParser(usage="%(prog)s [-h] [-a argA [-b argB]]")

parser.add_argument("-a",Metavar="argA",help="this is the 'a' argument")
parser.add_argument("-b",Metavar="argB",help="only use 'b' when 'a' is used")

myArgs = parser.parse_args()

if myArgs.aaa_arg == None and myArgs.bbb_arg != None:
    parser.error("only use 'b' when 'a' is used")

if myArgs.aaa_arg != None:
    print("AAA: " + myArgs.aaa_arg)
    if myArgs.bbb_arg != None:
        print("BBB: " + myArgs.bbb_arg)




>py test2.py

>py test2.py -a something
AAA: something

>py test2.py -a something -b somethingElse
AAA: something
BBB: somethingElse

>py test2.py -b somethingElse
usage: test2.py [-h] [-a argA [-b argB]]
test2.py: error: only use 'b' when 'a' is used

>py test2.py -h
usage: test2.py [-h] [-a argA [-b argB]]

optional arguments:
  -h,--help           show this help message and exit
  -a argA,--AAA argA  this is the 'a' argument
  -b argB,--BBB argB  only use 'b' when 'a' is used

>

解决方法

第一次尝试

问题是,被告知“-b”是有效参数的用户会被错误消息“-b somethingElse”无法识别而感到困惑。如果该用户随后显示帮助,他们将不会看到列出的“-b”。

第一个 parse_known_args() 处理,或者更确切地说忽略 -b。但它作用于 -h。第二个 parse_args() 是抱怨无法识别的 -b

ArgumentParser(add_help=False) 创建一个没有自动帮助的解析器;这是您的 resolve 的替代品。您可以在第一个 parse_know_args 之后添加自定义或标准帮助。

要考虑的另一件事是自定义 usage 字符串。

如果您不想让它抱怨 -b,请跳过 parse_args 或再次使用 parse_known_args

parser.error('custom message') 可用于显示使用情况的自定义错误。

argparse 没有提供一种方便的方法使一个参数以另一个参数为条件。通常我们建议在解析后进行这种测试,而不是尝试在解析时(或使用 2 个解析调用)进行所有测试。请记住,argparse 尝试以任何顺序处理 optionals-a foo -b bar-b bar -a foo 相同。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?