15

argparse次の2つの方法で使用されるコードを作成するために使用したいと思います。

./tester.py all
./tester.py name someprocess

つまり、いずれかallが指定されnameているか、追加の文字列が含まれています。

私は次のように実装しようとしました:

import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('all', action='store_true', \
        help = "Stops all processes")
group.add_argument('name', \
        help = "Stops the named process")

print parser.parse_args()

エラーが発生します

ValueError: mutually exclusive arguments must be optional

それを正しく行う方法はありますか?この場合、サブパーサーも避けたいと思います。

4

5 に答える 5

0

--allこれはサブパーサーの問題とまったく同じように見えることに同意します。 andを使用してオプションの引数にしたくない場合は、 andを完全--nameに無視して、次のセマンティクスを使用することをお勧めします。 :allname

  1. tester.py引数なしで呼び出された場合、すべてのプロセスを停止します。
  2. がいくつかの引数で呼び出された場合tester.py、それらのプロセスのみを停止します。

以下を使用して実行できます。

import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument('processes', nargs='*')
parsed = parser.parse(sys.argv[1:])
print parsed

次のように動作します。

$ python tester.py
名前空間(プロセス=[])
$ python tester.py proc1
名前空間 (プロセス = ['proc1'])

または、独自の構文を主張する場合は、カスタム クラスを作成できます。そして、実際には「相互に排他的なグループ」のケースはありません。 ifallが指定されていると仮定しているため、残りの引数は (nameが他の引数の 1 つであっても)無視され、 が指定されている場合は、それ以降はすべて無視nameされます。プロセスの名前と見なされます。

import argparse
import sys
class AllOrName(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        if len(values)==0:
            raise argparse.ArgumentError(self, 'too few arguments')
        if values[0]=='all':
            setattr(namespace, 'all', True)
        elif values[0]=='name':
            if len(values)==1:
                raise argparse.ArgumentError(self, 'please specify at least one process name')
            setattr(namespace, 'name', values[1:])
        else:
            raise argparse.ArgumentError(self, 'only "all" or "name" should be specified')

parser = argparse.ArgumentParser()
parser.add_argument('processes', nargs='*', action=AllOrName)
parsed = parser.parse_args(sys.argv[1:])
print parsed

次の動作で:

$ python argparse_test.py 名
使用法: argparse_test.py [-h] [プロセス [プロセス ...]]
argparse_test.py: エラー: 引数プロセス: 少なくとも 1 つのプロセス名を指定してください

$ python argparse_test.py 名前 proc1
名前空間(名前=['proc1']、プロセス=なし)

$ python argparse_test.py すべて
名前空間 (すべて = True、プロセス = なし)

$ python argparse_test.py ホスト
使用法: argparse_test.py [-h] [プロセス [プロセス ...]]
argparse_test.py: エラー: 引数プロセス: "all" または "name" のみを指定する必要があります

$ python argparse_test.py
使用法: argparse_test.py [-h] [プロセス [プロセス ...]]
argparse_test.py: エラー: 引数プロセス: 引数が少なすぎます
于 2014-03-24T05:15:39.997 に答える
0

「または追加の文字列を含む名前。」

位置引数は追加の文字列を取ることができません

あなたにとって最良の解決策は(test.pyという名前)だと思います:

import argparse
p = argparse.ArgumentParser()
meg = p.add_mutually_exclusive_group()
meg.add_argument('-a', '--all', action='store_true', default=None)
meg.add_argument('-n', '--name', nargs='+')
print p.parse_args([])
print p.parse_args(['-a'])
print p.parse_args('--name process'.split())
print p.parse_args('--name process1 process2'.split())
print p.parse_args('--all --name process1'.split())

$ python test.py

Namespace(all=None, name=None)
Namespace(all=True, name=None)
Namespace(all=None, name=['process'])
Namespace(all=None, name=['process1', 'process2'])
usage: t2.py [-h] [-a | -n NAME [NAME ...]]
t2.py: error: argument -n/--name: not allowed with argument -a/--all
于 2014-03-24T04:15:36.740 に答える
-2

これはおそらくあなたが探しているものです:

group.add_argument('--all', dest=is_all, action='store_true')
group.add_argument('--name', dest=names, nargs='+')

--name を渡すと、リストに 1 つの値が必要になり、それらをリストとして保存します。

于 2013-04-04T12:25:16.343 に答える