簡體   English   中英

Python:參數解析器,可以正確處理子命令的全局選項

[英]Python: argument parser that handles global options to sub-commands properly

argparse在處理接收全局選項的子命令時失敗:

import argparse
p = argparse.ArgumentParser()
p.add_argument('--arg', action='store_true')
s = p.add_subparsers()
s.add_parser('test')

會有p.parse_args('--arg test'.split())工作,
但在p.parse_args('test --arg'.split())上失敗了。

有誰知道python參數解析器正確處理子命令的全局選項?

試試docopt

>>> from docopt import docopt

>>> usage = """
... usage: prog.py command [--test]
...        prog.py another [--test]
... 
... --test  Perform the test."""

>>> docopt(usage, argv='command --test')
{'--test': True,
 'another': False,
 'command': True}

>>> docopt(usage, argv='--test command')
{'--test': True,
 'another': False,
 'command': True}

您可以輕松地將此參數添加到兩個解析器(主解析器和子命令解析器):

import argparse                                                                  

main = argparse.ArgumentParser()                                                    
subparser = main.add_subparsers().add_parser('test')                                        

for p in [main,subparser]:                                                                  
   p.add_argument('--arg', action='store_true')                                 

print main.parse_args('--arg test'.split()).arg                                     
print main.parse_args('test --arg'.split()).arg

編輯 :正如@hpaulj在注釋中指出的那樣,還有一些parents參數可以傳遞給ArgumentParser構造函數或add_parser方法。 您可以在此值列表中列出作為新值的基礎的解析器。

import argparse

base = argparse.ArgumentParser(add_help=False)
base.add_argument('--arg', action='store_true')

main = argparse.ArgumentParser(parents=[base])
subparser = main.add_subparsers().add_parser('test', parents=[base])

print main.parse_args('--arg test'.split()).arg
print main.parse_args('test --arg'.split()).arg

更多示例/文檔:

尋找在python中給出命令行參數的最佳方法,其中一些參數是某些選項的req,而一些參數是其他選項的req

Python argparse - 為多個subparser添加參數 (我不確定這個問題是否與這個問題不重疊)

http://docs.python.org/dev/library/argparse.html#parents

這是一個骯臟的解決方法 -

import argparse
p = argparse.ArgumentParser()
p.add_argument('--arg', action='store_true')
s = p.add_subparsers()
s.add_parser('test')

def my_parse_args(ss):
    #parse the info the subparser knows about; don't issue an error on unknown stuff
    namespace,leftover=p.parse_known_args(ss) 
    #reparse the unknown as global options and add it to the namespace.
    if(leftover):
        s.add_parser('null',add_help=False)
        p.parse_args(leftover+['null'],namespace=namespace)

    return namespace

#print my_parse_args('-h'.split())  #This works too, but causes the script to stop.
print my_parse_args('--arg test'.split())
print my_parse_args('test --arg'.split())

這是有效的 - 您可以很容易地修改它以使用sys.argv (只需刪除拆分字符串“ ss ”)。 你甚至可以子類argparse.ArgumentParser並更換parse_argsmy_parse_args然后你永遠不會知道其中的差別-盡管子類來取代單一的方法似乎矯枉過正我。

但是,我認為這是使用subparser的一種非標准方式。 一般來說,預計全局期權將出現在subsparser期權之前,而不是之后。

Python世界中有大量的參數解析庫。 這里有一些我見過的,所有這些應該能夠解決你想要解決的問題(基於我最后一次玩它時對它們的模糊回憶):

  • opster - 我認為這是mercurial使用的,IIRC
  • docopt-這是一個新的,但使用一個有趣的方法
  • 懸崖 - 這是一個相對較新的項目,Doug Hellmann(PSF成員,virtualenvwrapper作者,普通黑客非凡)不僅僅是一個參數解析器,而是從頭開始設計來處理多級命令
  • 克林特 -另一個旨在成為“論證解析和更多”的項目,由Kenneth Reitz(Requests成名)制作。

解析器具有特定語法: command <global options> subcommand <subcommand ptions> ,您嘗試使用選項提供子命令,但您沒有定義一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM