5

ファイルを入力として受け入れ、ファイルの内容を処理してサーバーにプッシュするプログラムがあります。オプションのコマンド ライン スイッチを追加して、プログラムの「ドライ ラン」を指定し、それによってすべてのファイル クランチを実行しますが、サーバーへの書き込みはスキップします。コマンド ライン引数を取り込むために argparse を使用していますが、引数間で「OR」関数を実行する方法がわかりません。これが私が多かれ少なかれ探しているものです...

可能なオプション:

1) prog.py 入力ファイル サーバー名

2) prog.py 入力ファイル -d

3) prog.py 入力ファイル -d サーバー名

不許可:

1) prog.py 入力ファイル

サーバー名「OR」ドライランフラグのいずれかがコマンドラインにあることを確認したい。そして、両方があれば…それもOKです。(したがって、XOR ではなく OR です)。required=true と相互に排他的に使用すると、XOR を取得できます。しかし、両方が存在する「OR」としてこれを行う方法がわかりません。さらに複雑なことに、サーバー名は位置引数であり、dry run フラグはオプションの引数であり、コマンド ラインのどこにでも指定できます。誰かがこれをやってのける方法について考えを持っていますか?

4

3 に答える 3

7

これが私がすることです:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-d', '--dry-run', action='store_true')
parser.add_argument('input_file', type=argparse.FileType('r'))
parser.add_argument('servername', nargs='?')

args = parser.parse_args()
if args.servername is None and not args.dry_run:
    parser.error("Option 'servername' is required when not in dry-run mode.")

print args

例:

$ ./prog.py inputfile servername
Namespace(dry_run=False, input_file=<open file 'inputfile', mode 'r' at 0x283440>, servername='servername')
$ ./prog.py inputfile -d
Namespace(dry_run=True, input_file=<open file 'inputfile', mode 'r' at 0x2cf440>, servername=None)
$ ./prog.py -d inputfile servername
Namespace(dry_run=True, input_file=<open file 'inputfile', mode 'r' at 0x1f4440>, servername='servername')
$ ./prog.py inputfile
usage: prog.py [-h] [-d] input_file [servername]
prog.py: error: Option 'servername' is required when not in dry-run mode.

カスタム アクションを使用してこれを行うこともでき、同じ効果があります。

class ServernameAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        if values is None and not namespace.dry_run:
            parser.error("Option 'servername' is required when not in dry-run mode.")
        setattr(namespace, self.dest, values)

...
parser.add_argument('servername', nargs='?', action=ServernameAction)
...
于 2012-09-21T18:48:29.553 に答える
3

argparse検証のすべての可能な組み合わせを行うことはできないため、事後に独自の検証を追加する方法を学ぶ価値があります。例えば:

parser = argparse.ArgumentParser(epilog='Either foo or bar (or both) must be specified.')
parser.add_argument('--foo', help='do something.')
parser.add_argument('--bar', help='do something else.')
args = vars(parser.parse_args())
if not args['foo'] and not args['bar']:
  parser.error('Either foo or bar (or both) must be specified.')
于 2012-09-21T18:46:11.600 に答える
0

を使用するとサーバー名は無視される-dため、使用しようとすると確実にエラーが発生するデフォルト値を指定します (とにかく検証する必要がありますよね?)。

p.add_argument("server", default=None)

-dが与えられた場合、おそらくサーバー名を検証したり使用したりすることは決してなく、すべて問題ありません。そうしないと、コードが検証を試みたときに、問題のあるサーバー名が検出されます。

于 2012-09-21T18:46:50.930 に答える