【问题标题】:Handle invalid arguments with argparse in Python在 Python 中使用 argparse 处理无效参数
【发布时间】:2016-07-12 23:11:52
【问题描述】:

我正在使用argparse 解析命令行参数,默认情况下接收到无效参数时它会打印帮助消息并退出。是否可以在 argparse 接收到无效参数时自定义其行为?

一般来说,我想捕捉所有无效的参数并用它们做一些事情。我正在寻找类似的东西:

parser = argparse.ArgumentParser()
# add some arguments here
try:
    parser.parse_args()
except InvalidArgvsError, iae:
    print "handle this invalid argument '{arg}' my way!".format(arg=iae.get_arg())

这样我就可以拥有:

>> python example.py --invalid some_text
handle this invalid argument 'invalid' my way!

【问题讨论】:

  • 看来您已经按照自己的方式处理参数:您在消息中打印了无效参数。你有什么问题?
  • @Prune:没有InvalidArgsError 这样的东西。发布的代码实际上不起作用。
  • 我意识到没有这样的错误;但是,OP 已发布成功输出。我想我看到了修辞问题;谢谢。
  • @Prune OP 仅发布了所需的输出。不是实际输出。
  • 是的,我想我也能看出修辞问题,和张老师无关。

标签: python argparse


【解决方案1】:

您可能想使用parse_known_args,然后查看元组中的第二项,看看哪些参数未被理解。

也就是说,我相信这只会对 extra 参数有所帮助,而不是具有无效值的预期参数。

【讨论】:

  • 这看起来是argparse 提供的最佳选择。
【解决方案2】:

之前的一些问题:

Python argparse and controlling/overriding the exit status code

I want Python argparse to throw an exception rather than usage

可能还有更多。

argparse 文档讨论了使用parse_known_args。这将返回它无法识别的参数列表。这是处理一种错误的便捷方式。

它还谈到了编写自己的 errorexit 方法。您不喜欢的错误通过这两种方法传递。更改这些的正确方法是继承ArgumentParser,尽管您可以对现有的解析器进行猴子补丁。默认版本位于argparse.py 文件的末尾,因此您可以研究它们的作用。

第三种选择是尝试/排除 Systemexit。

try:
    parser=argparse.ArgumentParser()
    args=parser.parse_args()
except SystemExit:
    exc = sys.exc_info()[1]
    print(exc)

这样,error/exit 仍然会产生错误消息(到 sys.stderr),但您可以阻止退出并继续执行其他操作。

1649:~/mypy$ python stack38340252.py -x
usage: stack38340252.py [-h]
stack38340252.py: error: unrecognized arguments: -x
2

较早的一个问题抱怨parser.error 没有得到关于错误的太多信息;它只是得到一个格式化的消息:

def myerror(message):
    print('error message')
    print(message)

parser=argparse.ArgumentParser()
parser.error = myerror
args=parser.parse_args()

展示

1705:~/mypy$ python stack38340252.py -x
error message
unrecognized arguments: -x

您可以解析该消息以找出 -x 是无法识别的字符串。在对早期版本的改进中,它可以列出多个参数

1705:~/mypy$ python stack38340252.py foo -x abc -b
error message
unrecognized arguments: foo -x abc -b

查找self.error 以查看所有可能触发错误消息的情况。如果您需要更多想法,请关注特定类型的错误。

================

unrecognized arguments 错误是由调用parse_known_argsparse_args 产生的,如果extras 不为空,则会引发此错误。所以它的特殊信息是parse_known_args无法处理的字符串列表。

如果捕获ArgumentError,则parse_known_args 会调用self.error。通常,当特定参数(Action)出现问题时会产生这些。但是_parse_known_args 调用self.error 如果需要缺少操作,或者如果存在互斥组错误。 choices 可以产生不同的错误,type 也可以。

【讨论】:

    【解决方案3】:

    您可以尝试继承 argparse.ArgumentParser() 并覆盖 error 方法。

    来自 argparse 来源:

    def error(self, message):
            """error(message: string)
    
            Prints a usage message incorporating the message to stderr and
            exits.
    
            If you override this in a subclass, it should not return -- it
            should either exit or raise an exception.
            """
            self.print_usage(_sys.stderr)
            self.exit(2, _('%s: error: %s\n') % (self.prog, message))
    

    【讨论】:

    • 它被用于各种其他错误,但除了消息字符串之外,它无法访问用于自定义错误处理的太多有用信息。
    • @user2357112 是的,这是真的,但其他选择是覆盖 parse_args()/parse_known)_args() 本身或干预所有不方便的方法。
    • 我不知道有任何严重的尝试来重做 argparse 错误方法。该模块定义了几个基本的Error 类,但对它们没有多大作用。 ArgumentError 只是将参数名称添加到消息中。
    【解决方案4】:

    由于错误代码 2 是为内部 docker 使用而保留的,因此我使用以下内容来解析 docker 容器内脚本中的参数:

    ERROR_CODE = 1
    class DockerArgumentParser(argparse.ArgumentParser):
        def error(self, message):
            """error(message: string)
    
        Prints a usage message incorporating the message to stderr and
        exits.
    
        If you override this in a subclass, it should not return -- it
        should either exit or raise an exception.
    
        Overrides error method of the parent class to exit with error code 1 since default value is
        reserved for internal docker usage
        """
        self.print_usage(sys.stderr)
        args = {'prog': self.prog, 'message': message}
        self.exit(ERROR_CODE, '%(prog)s: error: %(message)s\n' % args)
    

    【讨论】:

      猜你喜欢
      • 2022-06-11
      • 2017-01-14
      • 2021-09-05
      • 1970-01-01
      • 2017-11-26
      • 2015-03-04
      • 2020-03-04
      • 2014-11-10
      • 2023-02-05
      相关资源
      最近更新 更多