programing

인수 구문:'x'가 있는 경우 'y' 인수가 필요합니다.

instargram 2023. 6. 11. 10:18
반응형

인수 구문:'x'가 있는 경우 'y' 인수가 필요합니다.

다음과 같은 요구 사항이 있습니다.

./xyifier --prox --lport lport --rport rport

인수 prox의 경우 action= 'store_true'를 사용하여 존재 여부를 확인합니다.저는 어떤 주장도 필요로 하지 않습니다.하지만 --prox가 설정되어 있으면 rport와 lport도 필요합니다.사용자 지정 조건부 코딩을 작성하지 않고 Argparse로 이 작업을 수행하는 쉬운 방법이 있습니까?

추가 코드:

non_int.add_argument('--prox', action='store_true', help='Flag to turn on proxy')
non_int.add_argument('--lport', type=int, help='Listen Port.')
non_int.add_argument('--rport', type=int, help='Proxy port.')

아니요, 상호 포함 옵션 집합을 만들 수 있는 추가 옵션은 없습니다.

이 문제를 해결하는 가장 간단한 방법은 다음과 같습니다.

if args.prox and (args.lport is None or args.rport is None):
    parser.error("--prox requires --lport and --rport.")

사실 이미 개선 제안을 포함한 공개 PR이 있습니다. https://github.com/python/cpython/issues/55797

당신은 조건부로 요구되는 논쟁을 하는 것에 대해 말하고 있습니다.@borntyping이 말한 것처럼 당신은 오류를 확인하고 할 수 있습니다.parser.error()아니면 그냥 관련된 요구사항을 적용할 수 있습니다.--prox새 인수를 추가할 때 사용합니다.

예를 들어 간단한 솔루션은 다음과 같습니다.

non_int.add_argument('--prox', action='store_true', help='Flag to turn on proxy')
non_int.add_argument('--lport', required='--prox' in sys.argv, type=int)
non_int.add_argument('--rport', required='--prox' in sys.argv, type=int)

이쪽입니다.required다음 중 하나를 수신합니다.True또는False사용자가 사용했는지 여부에 따라--prox이것은 또한 보장합니다.-lport그리고.-rport서로 독립적인 행동을 합니다.

메소드를 사용한 다음 추가하는 것은 어떻습니까?--lport그리고.--rport필요한 인수인 경우 인수--prox존재합니다.

# just add --prox arg now
non_int = argparse.ArgumentParser(description="stackoverflow question", 
                                  usage="%(prog)s [-h] [--prox --lport port --rport port]")
non_int.add_argument('--prox', action='store_true', 
                     help='Flag to turn on proxy, requires additional args lport and rport')
opts, rem_args = non_int.parse_known_args()
if opts.prox:
    non_int.add_argument('--lport', required=True, type=int, help='Listen Port.')
    non_int.add_argument('--rport', required=True, type=int, help='Proxy port.')
    # use options and namespace from first parsing
    non_int.parse_args(rem_args, namespace = opts)

네임스페이스를 제공할 수도 있습니다.opts나머지 인수를 두 번째로 구문 분석하는 동안 첫 번째 구문 분석 후 생성되었습니다.그렇게 하면 결국 모든 구문 분석이 완료된 후 모든 옵션이 포함된 단일 네임스페이스를 갖게 됩니다.

단점:

  • 한다면--prox존재하지 않습니다. 다른 두 종속 옵션은 네임스페이스에도 없습니다.당신의 사용 사례에 따르면,--prox이(가) 없으므로 다른 옵션에 발생하는 작업은 관련이 없습니다.
  • 파서가 전체 구조를 모르기 때문에 사용 메시지를 수정해야 합니다.
  • --lport그리고.--rport도움말 메시지에 표시 안 함

사용하시겠습니까?lport언제prox설정되지 않았습니다.만약 그렇지 않다면, 왜 만들지 않습니까?lport그리고.rport의 주장.prox예를 들면

parser.add_argument('--prox', nargs=2, type=int, help='Prox: listen and proxy ports')

그러면 사용자 입력이 절약됩니다.테스트하는 것도 그만큼 쉽습니다.if args.prox is not None:~하듯이if args.prox:.

받아들여진 대답은 저에게 아주 잘 어울렸습니다!테스트 없이 모든 코드가 깨지기 때문에 여기서는 승인된 답변을 테스트한 방법입니다. parser.error()을 제기하지 않습니다.argparse.ArgumentError오류 대신 프로세스를 종료합니다.테스트해야 합니다.SystemExit.

화를 내며.

import pytest
from . import parse_arguments  # code that rasises parse.error()


def test_args_parsed_raises_error():
    with pytest.raises(SystemExit):
        parse_arguments(["argument that raises error"])

단일 시험으로

from unittest import TestCase
from . import parse_arguments  # code that rasises parse.error()

class TestArgs(TestCase):

    def test_args_parsed_raises_error():
        with self.assertRaises(SystemExit) as cm:
            parse_arguments(["argument that raises error"])

영감을 받은 제품:unit test를 사용하여 argparse 테스트 - 종료 오류

저는 이렇게 했습니다.

if t or x or y:
    assert t and x and y, f"args: -t, -x and -y should be given together"

언급URL : https://stackoverflow.com/questions/19414060/argparse-required-argument-y-if-x-is-present

반응형