2013-04-03 77 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