인수 구문:'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
'programing' 카테고리의 다른 글
명령줄에서 Windows 이벤트 로그 소스를 만드는 방법은 무엇입니까? (0) | 2023.06.11 |
---|---|
휴대용 분기 예측 힌트 (0) | 2023.06.11 |
R에서 data.frame의 처음 4개 행을 선택합니다. (0) | 2023.06.11 |
첫 번째 N 키 반환: dict에서 값 쌍 (0) | 2023.06.11 |
노드가 없는 타이프스크립트 명령줄 컴파일제이에스 (0) | 2023.06.11 |