找到你要的答案

Q:Python3 override argparse error

Q:argparse Python3覆盖误差

I'm creating a program as a assignment in my school, I'm all done with it except one thing. We have to make the program exit with different codes depending on how the execution went. In my program I'm processing options using "argparse" and when I use built-in functions like "version" I've managed to override the exit-code, but if I write a option that doesn't exist, then it won't work. It gives me the "unrecognized error"-message, and exits with code "0", I need it to exit with code 1. Is there anyway to do this? Been driving me nuts, have struggled with it for days now...

Thanks in advance! /feeloor

I'm creating a program as a assignment in my school, I'm all done with it except one thing. We have to make the program exit with different codes depending on how the execution went. In my program I'm processing options using "argparse" and when I use built-in functions like "version" I've managed to override the exit-code, but if I write a option that doesn't exist, then it won't work. It gives me the "unrecognized error"-message, and exits with code "0", I need it to exit with code 1. Is there anyway to do this? Been driving me nuts, have struggled with it for days now...

Thanks in advance! /feeloor

answer1: 回答1:

Use sys.exit(returnCode) to exit with particular codes. Obviously on linux machines you need to no 8 bit right shift inorder to get the right return code.

使用系统退出(returnCode)与特定的代码退出。显然在Linux机器上你需要8位没有右移,以便得到正确的返回代码。

answer2: 回答2:

To achieve something like this, inherit from argparse.ArgumentParser and reimplement the exit method (or perhaps the error method if you like).

For example:

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)

要实现这样的事情,从argparse.argumentparser和执行退出方法(或者误差的方法,如果你喜欢)。

例如:

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)
answer3: 回答3:

From the Python argparse documentation

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.

They both get a message, and pass it on. error adds usage and passes it on to exit. You can customize both in a subclassed Parser.

There are also examples of error catching and redirection the unittest file, test/test_argparse.py.

A problem with using a try/except wrapper is that the error information is written to sys.stderr, and not incorporated in the 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>)

The exit number is available in the exc_info, but not the message.

One option is to redirect sys.stderr at the same time as I do that try/except block.

Here's an example of changing the exit method and wrapping the call in a try block:

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 lets me replace methods of existing objects. I don't recommend this in production code, but it is convenient when trying ideas. I capture the Error (my choice of ValueError is arbitrary), and save the message for later display or testing.

Generally the type of error (e.g. TypeError, ValueError, etc) is part of the public API, but the text of error is not. It can be refined from one Python release to the next without much notification. So you test for message details at your own risk.

从Python argparse文档

http:/ /文档。Python。org / 3 /图书馆/ argparse HTML #退出方法。

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.

他们都得到一个信息,并传递它。错误添加使用并将其传递到退出。您可以自定义在一个子类解析器。

也有些错误捕获和重定向的测试文件,测试/ test_argparse.py。

用尝试/除了包装的一个问题是,错误信息写入到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是可用的,但没有消息。

一种选择是重定向的用法是我同时做试块/除。

这里是一个例子,改变退出方法和包装的调用在尝试块:

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释放到下一个没有太多的通知。所以你在自己的风险测试信息的细节。

answer4: 回答4:

I solved the problem catching SystemExit and determining what error by simply testing and comparing. Thanks for all the help guys!

I solved the problem catching SystemExit and determining what error by simply testing and comparing. Thanks for all the help guys!

python  python-3.x  override  argparse  exit-code