162

python argparseでサブコマンドを使用すると、選択した引数を取得できます。

parser = argparse.ArgumentParser()
parser.add_argument('-g', '--global')
subparsers = parser.add_subparsers()   
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-c', '--count')
bar_parser = subparsers.add_parser('bar')
args = parser.parse_args(['-g', 'xyz', 'foo', '--count', '42'])
# args => Namespace(global='xyz', count='42')

したがってargs、は含まれていません'foo'。グローバル引数の可能性があるため、単に書き込むだけsys.argv[1]では機能しません。サブコマンド自体を取得するにはどうすればよいですか?

4

3 に答える 3

222

argparseサブコマンドに関するPythonドキュメントの一番下には、これを行う方法が説明されています。

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-g', '--global')
>>> subparsers = parser.add_subparsers(dest="subparser_name") # this line changed
>>> foo_parser = subparsers.add_parser('foo')
>>> foo_parser.add_argument('-c', '--count')
>>> bar_parser = subparsers.add_parser('bar')
>>> args = parser.parse_args(['-g', 'xyz', 'foo', '--count', '42'])
>>> args
Namespace(count='42', global='xyz', subparser_name='foo')

set_defaults()私が見つけた例のすぐ上で参照されている方法を使用することもできます。

于 2011-01-01T21:10:50.677 に答える
27

ArgumentParser.add_subparsersdest次のように記述された正式な引数があります。

dest-サブコマンド名が格納される属性の名前。デフォルトNoneでは、値は保存されません

サブパーサーを使用した単純なタスク関数レイアウトの以下の例では、選択されたサブパーサーはにありparser.parse_args().subparserます。

import argparse


def task_a(alpha):
    print('task a', alpha)


def task_b(beta, gamma):
    print('task b', beta, gamma)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='subparser')

    parser_a = subparsers.add_parser('task_a')
    parser_a.add_argument(
        '-a', '--alpha', dest='alpha', help='Alpha description')

    parser_b = subparsers.add_parser('task_b')
    parser_b.add_argument(
        '-b', '--beta', dest='beta', help='Beta description')
    parser_b.add_argument(
        '-g', '--gamma', dest='gamma', default=42, help='Gamma description')

    kwargs = vars(parser.parse_args())
    globals()[kwargs.pop('subparser')](**kwargs)
于 2017-07-06T12:05:08.397 に答える
2

これは私の最近の仕事のいくつかで非常に便利だったので、この答えを投稿したかっただけです。このメソッドはデコレータを使用し(ただし、従来の@構文では使用されません)、recommendedset_defaultsがすでにサブパーサーで使用されている場合に特に便利です。

import argparse
from functools import wraps
import sys

def foo(subparser):
    subparser.error('err')

def bar(subparser):
    subparser.error('err')

def map_subparser_to_func(func, subparser):
    @wraps(func)
    def wrapper(*args, **kwargs):
        return func(subparser, *args, **kwargs)
    return wrapper

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()

foo_parser = subparsers.add_parser('foo')
foo_parser.set_defaults(func = map_subparser_to_func(foo, foo_parser))

bar_parser = subparsers.add_parser('bar')
bar_parser.set_defaults(func = map_subparser_to_func(bar, bar_parser))

args = parser.parse_args(sys.argv[1:])
args.func()

map_subparser_to_func関数を変更して、サブパーサーを直接渡すのではなく、関数内のクラス属性またはグローバル変数に設定できます。またwrapper、関数の従来のデコレーターに作り直すこともできますが、別のレイヤーを追加する必要があります。

このようにして、オブジェクトへの直接参照があります。

于 2021-08-27T09:42:55.507 に答える