9

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引数パーサーを知っている人はいますか?

4

5 に答える 5

5

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}
于 2012-06-05T13:39:58.413 に答える
5

この引数は、両方のパーサー(メインパーサーとサブコマンドパーサー)に簡単に追加できます。

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渡すことができる引数もあります。この値には、新しいパーサーのベースとなるパーサーをリストできます。ArgumentParseradd_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でコマンドライン引数を指定する最良の方法を探しています。一部のパラメーターは一部のオプションで必須であり、一部のパラメーターは他のオプションで必須です

Python argparse-複数のサブパーサーに引数を追加します(この質問がこれと重複しすぎていないかどうかはわかりません)

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

于 2013-08-29T17:19:02.523 に答える
3

Pythonの世界には、たくさんの引数解析ライブラリがあります。これが私が見たいくつかのことです、それらのすべてはあなたが解決しようとしている問題に対処することができるはずです(私が最後に彼らと遊んだときのそれらのあいまいな回想に基づいて):

  • opster —これが水銀が使用するものだと思います、IIRC
  • docopt —これは新しいものですが、興味深いアプローチを使用しています
  • cliff —これはDoug Hellmann(PSFメンバー、virtualenvwrapperの作成者、一般的なハッカーの並外れた存在)による比較的新しいプロジェクトです。単なる引数パーサーではありませんが、マルチレベルのコマンドを処理するようにゼロから設計されています。
  • clint —「引数の解析など」を目的とした別のプロジェクト。これは(Requestsの名声の)KennethReitzによるものです。
于 2012-06-05T11:52:35.730 に答える
2

これが汚い回避策です-

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

ただし、これはサブパーサーを使用するための非標準的な方法のほんの一部だと思います。一般に、グローバルオプションは、サブパーサーオプションの後ではなく、前に来ると予想されます。

于 2012-06-05T11:46:16.263 に答える
1

パーサーには特定の構文があります。command <global options> subcommand <subcommand ptions>、サブコマンドにオプションを指定しようとしていますが、定義していません。

于 2012-06-05T11:47:52.540 に答える