Python3 覆盖 argparse 错误
Posted
技术标签:
【中文标题】Python3 覆盖 argparse 错误【英文标题】:Python3 override argparse error 【发布时间】:2015-10-08 09:07:14 【问题描述】:我正在创建一个程序作为我学校的作业,除了一件事,我已经完成了它。 我们必须根据执行的方式使用不同的代码使程序退出。在我的程序中,我正在使用“argparse”处理选项,当我使用像“version”这样的内置函数时,我设法覆盖了退出代码,但是如果我编写了一个不存在的选项,那么它就赢了不行。它给了我“无法识别的错误”消息,并以代码“0”退出,我需要它以代码 1 退出。有什么办法吗?一直让我发疯,已经为此苦苦挣扎了好几天...
提前致谢! /感觉
【问题讨论】:
【参考方案1】:使用 sys.exit(returnCode) 以特定代码退出。显然,在 linux 机器上,您不需要 8 位右移即可获得正确的返回码。
【讨论】:
是的,我知道,问题是如何覆盖 argparse 错误?因为当一个选项无法识别时,它会自动退出并显示错误代码 0,我想覆盖它以便我可以将其更改为退出代码 1... 使用 try except 块捕获错误,并根据异常退出使用不同的代码...提示:使用类似 sys.exc_info() 的方法来检测异常的类型..跨度> 【参考方案2】:要实现这样的目标,请从 argparse.ArgumentParser
继承并重新实现 exit
方法(或者如果您愿意,也可以是 error
方法)。
例如:
class Parser(argparse.ArgumentParser):
# the default status on the parent class is 0, we're
# changing it to be 1 here ...
def exit(self, status=1, message=None):
return super().exit(status, message)
【讨论】:
这是我想我需要做的事情,但我需要实际查看错误是什么,并根据错误给出退出代码,因为正如我所说,退出状态“1”是当错误输入选项时,“0”是程序退出成功和“2”的时候是“命令”是错误的...希望您明白我的意思,抱歉,如果我有点不清楚.. span > 然后覆盖ArgumentParser
上的更多方法,例如error
...主动性等等...
是的,这就是我想做的,但我似乎找不到他们的“名字”或者怎么做?对不起,我对 python 很陌生..【参考方案3】:
来自 Python argparse 文档
https://docs.python.org/3/library/argparse.html#exiting-methods
16.4.5.9. Exiting methods
ArgumentParser.exit(status=0, message=None)
This method terminates the program, exiting with the specified status and, if given, it prints a message before that.
ArgumentParser.error(message)
This method prints a usage message including the message to the standard error and terminates the program with a status code of 2.
他们都得到了一个message
,并把它传递下去。 error
添加 usage
并将其传递给 exit
。您可以在子类解析器中自定义两者。
还有错误捕获和重定向单元测试文件test/test_argparse.py
的示例。
使用try/except
包装器的一个问题是error
信息被写入sys.stderr
,而不是合并到sys.exc_info
。
In [117]: try:
parser.parse_args(['ug'])
except:
print('execinfo:',sys.exc_info())
.....:
usage: ipython3 [-h] [--test TEST] [--bar TEST] test test
ipython3: error: the following arguments are required: test
execinfo: (<class 'SystemExit'>, SystemExit(2,), <traceback object at 0xb31fb34c>)
退出号在exc_info
中可用,但在消息中没有。
一种选择是重定向sys.stderr
,同时重定向try/except
块。
以下是更改exit
方法并将调用包装在try 块中的示例:
In [155]:
def altexit(status, msg):
print(status, msg)
raise ValueError(msg)
.....:
In [156]: parser.exit=altexit
In [157]:
try:
parser.parse_args(['--ug','ug','ug'])
except ValueError:
msg = sys.exc_info()[1]
.....:
usage: ipython3 [-h] [--test TEST] [--bar TEST] test test
2 ipython3: error: unrecognized arguments: --ug
In [158]: msg
Out[158]: ValueError('ipython3: error: unrecognized arguments: --ug\n')
Python
让我替换现有对象的方法。我不建议在生产代码中这样做,但在尝试想法时很方便。我捕获错误(我对 ValueError 的选择是任意的),并保存消息以供以后显示或测试。
通常错误类型(例如 TypeError、ValueError 等)是公共 API 的一部分,但错误文本不是。它可以在没有太多通知的情况下从一个 Python 版本改进到下一个版本。因此,您需要自行承担测试消息详细信息的风险。
【讨论】:
【参考方案4】:我通过简单的测试和比较解决了捕获 SystemExit 并确定错误的问题。 感谢大家的帮助!
【讨论】:
以上是关于Python3 覆盖 argparse 错误的主要内容,如果未能解决你的问题,请参考以下文章