2013-04-03 24 views
2

由于某些原因,我的程序有非标准的命令行选项。我的程序也需要一个长期的选项,也有一个' - '。例如,有效的命令行选项是'-f'/'-foo'。短期和长期期权都需要用空格或'='分隔参数。在python中使用optparse解析非GNU标准选项

我想解析这个使用optparse,但我明白optparse不支持非GNU标准选项。有没有办法来调整optparse来做到这一点?

+0

注意:自python版本2.7开始,不鼓励使用* optparse *。 optparse模块已弃用,不会进一步开发;开发将继续使用* argparse *模块。有关更多信息,请参见[PEP 0389] [1]。 [1]:http://www.python.org/dev/peps/pep-0389/ – shakaran 2013-04-03 22:32:45

+1

@shakaran:有一点小技巧,你使用'[inline link format](http://example.com) '(显示为[内嵌链接格式](http://example.com))在注释中进行链接。 – nneonneo 2013-04-03 22:49:28

+0

谢谢!我会在下一个评论链接中看到它。不幸的是,我无法编辑我最近的评论,据我所知。 – shakaran 2013-04-03 22:52:06

回答

2

这里有一个温和的hackish方式做你所需要的。

子类OptionOptionParser和补丁的一些方法:

from optparse import Option, OptionError, OptionParser 

class MyOption(Option): 
    def _set_opt_strings(self, opts): 
     for opt in opts: 
      if len(opt) < 2: 
       raise OptionError(
        "invalid option string %r: " 
        "must be at least two characters long" % opt, self) 
      elif len(opt) == 2: 
       self._short_opts.append(opt) 
      else: 
       self._long_opts.append(opt) 

class MyOptionParser(OptionParser): 
    def _process_args(self, largs, rargs, values): 
     while rargs: 
      arg = rargs[0] 
      if arg == "--": 
       del rargs[0] 
       return 
      elif arg[0:2] == "--": 
       self._process_long_opt(rargs, values) 
      elif arg[:1] == "-" and len(arg) > 1: 
       if len(arg) > 2: 
        self._process_long_opt(rargs, values) 
       else: 
        self._process_short_opts(rargs, values) 
      elif self.allow_interspersed_args: 
       largs.append(arg) 
       del rargs[0] 
      else: 
       return 

现在你可以做

parser = MyOptionParser() 
parser.add_option(MyOption("-f", "-file", dest="filename", 
       help="write report to FILE", metavar="FILE")) 
parser.add_option(MyOption("-q", "-quiet", 
       action="store_false", dest="verbose", default=True, 
       help="don't print status messages to stdout")) 

有了这个,parser将接受-file作为一个选项(也不会接受如-fq )。

+0

非常感谢。这实际上对我有帮助。但是,在打印帮助或提到无效选项时,会打印 - 选项。要清楚。在上面的代码中,如果我在命令行中将选项设置为-fle,那么错误消息将为:“no such option --fle”。我可以在哪里更改此行为,以便将其打印为“无此选项:-fle”? – user2242512 2013-04-03 23:43:13

+0

要做到这一点,您需要修补'Option'。我已经为我的答案添加了必要的补丁。 – nneonneo 2013-04-04 00:02:51

+0

据我所知,这有助于设置一个单一的长选项 - 在“选项”中,所以当它打印帮助信息时,它将打印选项 - 单。但是显示为无效选项的错误消息显示为双破折号。例如:考虑你上面提到的选项。在命令行中,如果我给出一个选项“-invalid”(一个不存在的选项),它会打印一个错误消息“no such option --invalid”(这有双重短划线,但我在命令中给出了一个短划线线)。我不明白它是如何将cmd行参数更改为双破折号。 – user2242512 2013-04-04 05:59:55

0

我不认为有什么办法可以调整optparse(尽管我不确定),但是可以处理C风格命令行选项的替代方法。

1

optparse documentation

选项:
用于提供额外的信息,以指导或自定义程序的执行参数。选项有许多不同的语法;传统的Unix语法是一个连字符(“ - ”),后面跟着单个字母,例如。 -x-F。而且,传统的Unix语法允许将多个选项合并为单个参数,例如, -x -F相当于-xF。 GNU项目引入了--后跟一系列连字符分隔的单词,例如--file--dry-run这些是由optparse提供的唯一两种选项语法。

(强调)

所以,不,你不能指定的处理参数与optparse其他方式。但是,您可以使用sys module中的argv来解析自己的论点。

这将是更多的工作,但它可能看起来像:

from sys import argv 
for arg in argv: 
    if arg.startswith("-") or arg.startswith("--"): 
     # Parse the argument 
+0

感谢您的回复。我已经想到了这一点,但我想知道是否有办法使用optparse来做到这一点。现在,我正在使用解析器。add_option添加一个正常的长选项。然后,我修改了argv以在长选项之前附加 - 以便optparse.OptionParser可以解析它。例如: parser.add_option(“ - foo”,dest =“foo”)。如果命令行选项是-foo,我会解析它并将其设置为'--foo'并将其作为参数发送给解析器函数。但这里的问题在于,它会将选项打印为--foo,但我希望将它作为-foo。我可以更改帮助文本吗? – user2242512 2013-04-03 22:33:44