简体   繁体   English

optparse的异常处理

[英]exception handling for optparse of python

HI, guys. 嗨,大家好。

I am using cmd and optparse to develop a CLI.py for a collection of already-functional classes (CDContainer, CD, etc.). 我正在使用cmd和optparse来开发CLI.py,用于已经正常运行的类(CDContainer,CD等)的集合。 The following are some parts of the code. 以下是代码的某些部分。 I have a problem here. 我这里有问题。 when there are exceptions(wrong input type or missing values), the optparse will exit the whole program instead of the specific command method. 当存在异常(错误的输入类型或缺少值)时,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)

Under ">python", if I type CLI.py, then I will have (Cmd), so I could type command like "(Cmd)addcd -t 3 -n thriller". 在“> python”下,如果我输入CLI.py,那么我将有(Cmd),所以我可以键入命令“(Cmd)addcd -t 3 -n thriller”。 but if I type "addcd -tr -n 3", then optparse will terminate the whole CLI.py and exit. 但如果我输入“addcd -tr -n 3”,那么optparse将终止整个CLI.py并退出。 This is not good for me. 这对我不好。 I want to remind the user for each method, instead of terminating the whole program. 我想提醒用户每个方法,而不是终止整个程序。

however, the optparse documentation says "the whole program exits". 然而,optparse文档说“整个程序退出”。 so I could not use optparse "blindly". 所以我不能“盲目地”使用optparse。 what can I do? 我能做什么?

The optparse documentation says this: optparse文档说明了这一点:

If optparse's default error-handling behaviour does not suit your needs, you'll need to subclass OptionParser and override its exit() and/or error() methods. 如果optparse的默认错误处理行为不符合您的需求,您需要继承OptionParser并覆盖其exit()和/或error()方法。

Ideally you'd define a new type of exception, subclass optparse , raise the exception in the exit() or error() method that you've overridden, and then catch it and deal with it as needed. 理想情况下,您将定义一种新类型的异常,子类optparse ,在您重写的exit()error()方法中引发异常,然后捕获它并根据需要处理它。

You can cheat, though. 不过你可以作弊。 If you want the error message printed but just don't want the program to exit, then you can catch the SystemExit exception to catch where optparse is trying to exit and stop it. 如果您希望打印错误消息但只是不希望程序退出,那么您可以捕获SystemExit异常以捕获optparse尝试退出并停止它的位置。

So, for example: 所以,例如:

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

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

or to override the method: 或覆盖方法:

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)

and then: 接着:

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)

It probably has to do with the types that you're passing to the CD class: without seeing it, there's a really good chance that it's failing there. 它可能与您传递给CD类的类型有关:没有看到它,它很可能会失败。 Before creating that object and passing the arguments, it's a really good idea to clean that data, ensure it's the correct type, and perform any other checks that you see as being reasonable. 在创建该对象并传递参数之前,清理该数据,确保它是正确的类型并执行您认为合理的任何其他检查是一个非常好的主意。

    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

The custom exception class still can't handle '-h --help' option that displays the default help context. 自定义异常类仍然无法处理显示默认帮助上下文的“-h --help”选项。

What I did I used sys.argv before try - except block to handle help function. 我做了什么我在尝试之前使用了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

Thanks for the tips by the way. 谢谢你的提示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM