Python中optparse的异常处理
大家好。
我正在使用命令行工具(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 个回答
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
顺便说一下,谢谢你的建议。
这可能跟你传给CD类的数据类型有关:如果不看代码,很有可能就是在这里出问题了。在创建那个对象并传递参数之前,最好先处理一下这些数据,确保它们是正确的类型,并进行其他你认为合理的检查。
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)