Python中optparse的异常处理

2 投票
3 回答
5305 浏览
提问于 2025-04-16 06:03

大家好。

我正在使用命令行工具(cmd)和选项解析库(optparse)来开发一个叫做CLI.py的程序,这个程序是为了管理一些已经能正常工作的类,比如CDContainer、CD等等。下面是代码的一些部分。我遇到了一个问题:当输入错误(比如输入类型不对或者缺少值)时,optparse会直接退出整个程序,而不是只退出当前的命令方法。

import cmd
class CLI(cmd.Cmd):

    def do_addcd(self, line):
        args=line.split()
        parser = OptionParser()
        parser.add_option("-t", "--track", dest="track_number", type="int",
            help="track number")
        parser.add_option("-n", "--cdname", dest="cd_name", type="string",
            help="CD name")
        (options, positional_args) = parser.parse_args(args[0:])
        cd_obj= CD()
        cd_obj.addCD(options.track_number, options.cd_name)

在命令行中输入“>python”,如果我输入CLI.py,程序就会启动(Cmd),这样我就可以输入像“(Cmd)addcd -t 3 -n thriller”这样的命令。但是如果我输入“addcd -t r -n 3”,optparse就会直接终止整个CLI.py并退出。这对我来说不好。我希望能在每个方法中给用户一些提示,而不是直接结束整个程序。

不过,optparse的文档上说“整个程序会退出”。所以我不能“盲目”使用optparse。我该怎么办呢?

3 个回答

0
    try:
    parser = ModifiedOptionParser()
    parser.add_option("-t", "--track", dest="track_number", type="int",
        help="track number")
    (options, positional_args) = parser.parse_args(args[0:])
except OptionParsingError, e:
    print 'There was a parsing error: %s' % e.msg
    return
except OptionParsingExit, e:
    print 'The option parser exited with message %s and result code %s' % (e.msg, e.status)
    return

这个自定义的异常类还是不能处理 '-h --help' 这个选项,它是用来显示默认帮助信息的。

我在 try - except 块之前使用了 sys.argv 来处理帮助功能。

if sys.argv[1] == '-h' or sys.argv[1] == '--help':
    raise Exception('help')

parser = ModifiedOptionParser()
...
except Exception as value:
    status = str(value)
    if status is 'help':
         parser.print_help()
         return -1    # I need to set different return value

顺便说一下,谢谢你的建议。

0

这可能跟你传给CD类的数据类型有关:如果不看代码,很有可能就是在这里出问题了。在创建那个对象并传递参数之前,最好先处理一下这些数据,确保它们是正确的类型,并进行其他你认为合理的检查。

11

optparse 的文档中提到:

如果 optparse 默认的错误处理方式不符合你的需求,你需要创建一个新的类,继承自 OptionParser,并重写它的 exit() 和/或 error() 方法。

理想情况下,你应该定义一个新的异常类型,继承 optparse,在你重写的 exit()error() 方法中抛出这个异常,然后捕获它并根据需要处理。

不过,你也可以走捷径。如果你想打印错误信息,但不想让程序退出,你可以捕获 SystemExit 异常,这样就能阻止 optparse 尝试退出程序。

例如:

try:    
    (options, positional_args) = parser.parse_args(args[0:])
except SystemExit:
    return

cd_obj= CD()
cd_obj.addCD(options.track_number, options.cd_name)

或者重写这个方法:

import optparse

class OptionParsingError(RuntimeError):
    def __init__(self, msg):
        self.msg = msg

class OptionParsingExit(Exception):
    def __init__(self, status, msg):
        self.msg = msg
        self.status = status

class ModifiedOptionParser(optparse.OptionParser):
    def error(self, msg):
        raise OptionParsingError(msg)

    def exit(self, status=0, msg=None):
        raise OptionParsingExit(status, msg)

然后:

try:
    parser = ModifiedOptionParser()
    parser.add_option("-t", "--track", dest="track_number", type="int",
        help="track number")
    (options, positional_args) = parser.parse_args(args[0:])
except OptionParsingError, e:
    print 'There was a parsing error: %s' % e.msg
    return
except OptionParsingExit, e:
    print 'The option parser exited with message %s and result code %s' % (e.msg, e.status)
    return

cd_obj= CD()
cd_obj.addCD(options.track_number, options.cd_name)

撰写回答