鍍金池/ 問答/Python  網(wǎng)絡(luò)安全/ python argparse 使用[-h]時如何才能不退出程序

python argparse 使用[-h]時如何才能不退出程序

argparse 在使用[-h]時顯示幫助,然后就退出了,如何才能不退出交互界面,等待下一個輸入?

while True:
    cmd = input('>>>')
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', help='foo')
    parser.parse_args(cmd.split())

這樣輸入[-h]的時候:

>>>-h
usage: test.py [-h] [-f F]

optional arguments:
  -h, --help  show this help message and exit
  -f F        foo

程序就結(jié)束了,現(xiàn)在我只要'show this help message',而不需要'exit',請問要如何做?謝謝!

回答
編輯回答
久舊酒

根本原因在于, argparse.parse_args() 會在出錯和 -h 時執(zhí)行 sys.exit() . 這個可以通過捕獲 SystemExit 異常來解決:

import argparse

while True:
    cmd = input('>>>')
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', help='foo')

    try:
        parser.parse_args(cmd.split())
    except SystemExit:
        print("ignoring SystemExit")

另外1: 建議不要把初始化代碼放在循環(huán)塊中, 我覺得這樣寫會更好:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-f', help='foo')

while True:
    cmd = input('>>>')
    try:
        parser.parse_args(cmd.split())
    except SystemExit:
        print("ignoring SystemExit")

另外2: 提出 python 問題時, 不妨注明你用的是 python2 還是 python3. 你的代碼中, 有些規(guī)則在兩個版本間有區(qū)別.

參考 - argparse.parse_args() 源碼片段:

    def parse_args(self, args=None, namespace=None):
        args, argv = self.parse_known_args(args, namespace)
        if argv:
            msg = _('unrecognized arguments: %s')
            self.error(msg % ' '.join(argv))
        return args
class _HelpAction(Action):

    def __init__(self,
                 option_strings,
                 dest=SUPPRESS,
                 default=SUPPRESS,
                 help=None):
        super(_HelpAction, self).__init__(
            option_strings=option_strings,
            dest=dest,
            default=default,
            nargs=0,
            help=help)

    def __call__(self, parser, namespace, values, option_string=None):
        parser.print_help()
        parser.exit()
    def exit(self, status=0, message=None):
        if message:
            self._print_message(message, _sys.stderr)
        _sys.exit(status)

    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)
        args = {'prog': self.prog, 'message': message}
        self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
2017年3月30日 10:43