python optparse的异常处理

问题描述:

嗨,伙计们。python optparse的异常处理

我正在使用cmd和optparse来为已有功能的类(CDContainer,CD等)集合开发CLI.py。以下是代码的一些部分。我在这里遇到问题。当出现异常(错误的输入类型或缺失值)时,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) 

在 “>蟒”,如果I型CLI.py, 然后我将具有(CMD),所以可以输入像命令 “(CMD)addcd -t 3 -n惊悚片”。 但如果我输入“addcd -t r -n 3”,则optparse将终止整个CLI.py并退出。 这对我不好。我想提醒用户每种方法,而不是终止整个程序。

但是,optparse文档显示“整个程序退出”。所以我不能“盲目”地使用optparse。我能做什么?

optparse文档这样说:

如果optparse的默认错误处理行为不适合你的需求,你需要继承OptionParser并覆盖其出口()和/或错误()方法。

理想情况下,你会定义一个新的类型的异常,子类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) 
+0

我明白了。那么我不使用optparse?我自己解析参数并相应地进行分析。如果我使用optparse,正如你所说的那样,我应该以某种方式覆盖它的退出或错误方法,但我并不确信我能做到。 – pepero 2010-10-25 12:20:49

+1

我会坚持optparse。它将保持选项解析行为一致,并且编写遵循常规约定的参数解析器将是很多工作。 我已经用覆盖错误方法的示例更新了我的答案。 – 2010-10-25 12:39:50

+0

嗨,Robie,非常感谢你用代码的详细回答!它符合我的意图!但只有一件事,当我调用method -help,例如addcd -h时,它会列出选项,然后退出程序。是否有可能解决它的“帮助”。非常感谢! – pepero 2010-10-25 13:03:10

它可能与你传递给CD类的类型有关:如果没有看到它,它很有可能会失败。在创建该对象并传递参数之前,清理这些数据,确保它是正确的类型并执行任何其他您认为合理的检查是非常好的主意。

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'选项帮助上下文。

我做了什么我尝试之前使用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 

感谢您的提示。