2

Python スクリプトに渡された引数に基づいてアクションを実行する必要があるテスト シナリオがあります。要件は次のとおりです。

test.py -a a1 -b b1 [[[-c c1] [-d d1]] | [-e e1 -f f1]]

  1. ユーザーは、必須の引数「-a」および「-b」を渡す必要があります。
  2. 引数「-c」および「-d」は、個別に渡すことができるオプションの引数です。
  3. 引数「-e」と「-f」はオプションの引数で、必須の引数と一緒に渡す必要があります。
  4. 「-c」または「-d」のいずれかが「-e」および「-f」とともに渡された場合、スクリプトは引数「-c」または「-d」に対してエラーを返す必要があります。
  5. 「-e」および「-f」が「-c」または「-d」とともに渡された場合、スクリプトは引数「-e」および「-d」に対してエラーを返す必要があります。

エラーは、すべてのオプション引数の一般的なエラーである可能性があります。

これまで、parents=オプションを使用して実行しようargparse.ArgumentParserとしましたが、渡された引数を読み取ろうとするとエラーが発生します。

import argparse


parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument('-a', type=str, required=True)
parent_parser.add_argument('-b', type=str, required=True)

one_parser = argparse.ArgumentParser(parents=[parent_parser])
one_parser.add_argument('-c', type=str, default="test")
one_parser.add_argument('-d', type=str, default="Default")

multi_parser = argparse.ArgumentParser(parents=[parent_parser])
multi_parser.add_argument('-e', type=str)
multi_parser.add_argument('-f', type=str)

if str(one_parser.parse_args().c):
    print(one_parser.parse_args())
elif str(multi_parser.parse_args().e):
    print(multi_parser.parse_args())

スクリプトを次のように実行すると:

test.py -a a1 -b b1 -e e1 -f f1

エラーが発生します:

usage: test.py [-h] -a A -b B [-c C] [-d D]
test.py: error: unrecognized arguments: -e e1 -f f1

Process finished with exit code 2

どんな指針も高く評価されます。ありがとうございました。

回答: 解決策はハックですが、うまくいきました。

import argparse


parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-a', type=str, required=True)
parser.add_argument('-b', type=str, required=True)
parser.add_argument('-c', type=str)
parser.add_argument('-d', type=str)
parser.add_argument('-e', type=str)
parser.add_argument('-f', type=str)
args = parser.parse_args()

a = str(args.a)
b = str(args.b)
c = str(args.c)
d = str(args.d)
e = str(args.e)
f = str(args.f)

if (e != "None" and f == "None") or (e == "None" and f != "None"):
    if c == "None" and d == "None":
        raise argparse.ArgumentTypeError("Both e and f arguments are required")
    elif c != "None" or d != "None":
        raise argparse.ArgumentTypeError("e and f are not supported with c or d")
if (c != "None" or d != "None") and (e != "None" or f != "None"):
    raise argparse.ArgumentTypeError("c and d are not supported with e and f")
if e == "None" and f == "None":
    if c == "None":
        c = "test"
    if d == "None":
        d = "Default"

IMO、argparser は引数の依存関係をより効率的に処理する必要があります。多分誰かが貢献して私たち全員を助けてくれるでしょう.. :)

4

1 に答える 1

1

あなたの問題は複数のパーサーを使用しています。引数グループが役立つ場合があります。

次に、引数が条件に準拠していることを自分で確認し、必要に応じて argparse.ArgumentError を発生させる必要があります。

これは、トリックを実行できるコード サンプルです。arguments_group は、-h パラメーターを文書化するためだけに機能します (argparser ヘルプ)

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-a", required=True)
parser.add_argument("-b", required=True)
first = parser.add_argument_group("group 1", "None, one or both")
first.add_argument("-c")
first.add_argument("-d")
second = parser.add_argument_group("group 2", "None or both")
second.add_argument("-e")
second.add_argument("-f")

args = parser.parse_args()

a = args.a
b = args.b
c = args.c
d = args.d
e = args.e
f = args.f

if (e is not None and f is None) or (e is None and f is not None):
    if c is None and d is None:
        raise argparse.ArgumentError("Both e and f arguments are required")
    elif c is None or d is not None:
        raise argparse.ArgumentError("e and f are not supported with c or d")
if (c is not None or d is not None) and (e is not None or f is not None):
    raise argparse.ArgumentError("c and d are not supported with e and f")
于 2020-01-09T14:01:40.687 に答える