Argparse :“선택적 인수”에 나열된 필수 인수?


229

다음 간단한 코드를 사용하여 일부 인수를 구문 분석합니다. 그중 하나가 필요합니다. 불행히도 사용자가 인수를 제공하지 않고 스크립트를 실행할 때 표시되는 사용법 / 도움말 텍스트에는 선택 사항이 아닌 인수가 있음을 나타내지 않으므로 매우 혼란스러워합니다. 파이썬이 인수가 선택적이 아님을 나타내도록 어떻게 할 수 있습니까?

코드는 다음과 같습니다.

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Foo')
    parser.add_argument('-i','--input', help='Input file name', required=True)
    parser.add_argument('-o','--output', help='Output file name', default="stdout")
    args = parser.parse_args()
    print ("Input file: %s" % args.input )
    print ("Output file: %s" % args.output )

필요한 인수를 제공하지 않고 위의 코드를 실행하면 다음과 같은 결과가 나타납니다.

usage: foo.py [-h] -i INPUT [-o OUTPUT]

Foo

optional arguments:
    -h, --help            show this help message and exit
    -i INPUT, --input INPUT
                          Input file name
    -o OUTPUT, --output OUTPUT
                          Output file name

5
사용 라인에서 -i INPUT부품은 대괄호로 둘러싸이지 않으며, 실제로 미묘함이 필요함을 나타냅니다. 또한 help매개 변수 를 통해 수동으로 설명 할 수 있습니다.
Jaime RGP

7
@JaimeRGP 예, 물론 충분하지는 않으며 눈에 띄지 않습니다. optional arguments필수 인수에 할당 된 그룹 이름 이 여전히 잘못되었습니다.
Acumenus

답변:


316

-또는 --로 시작하는 매개 변수 는 일반적으로 선택 사항으로 간주됩니다. 다른 모든 매개 변수는 위치 매개 변수이며 위치 함수 인수와 같은 설계 상 필요합니다. 선택적 인수가 필요할 수 있지만 이는 디자인과 약간 다릅니다. 그것들은 여전히 ​​비 포지셔닝 인수의 일부이므로, 필요하더라도 혼란스러운 헤더“선택적 인수”아래에 계속 나열됩니다. 그러나 사용법 부분에서 빠진 대괄호는 실제로 필요하다는 것을 보여줍니다.

설명서 도 참조하십시오 .

일반적으로 argparse 모듈은 -f 및 --bar와 같은 플래그가 선택적 인수를 나타내며 명령 행에서 항상 생략 할 수 있다고 가정합니다.

참고 : 필수 옵션은 일반적으로 사용자가 옵션이 선택적 일 것으로 기대하므로 가능한 한 피해야합니다.

즉 , 도움말 의 헤더 "위치 인수""선택적 인수" 는 인수가 자동으로 분리되는 두 개의 인수 그룹에 의해 생성됩니다. 이제 "해킹"하고 선택 사항의 이름을 변경할 수 있지만 훨씬 더 우아한 해결책은 "필수 이름 지정된 인수"(또는 호출하려는 대상)에 대한 다른 그룹을 만드는 것입니다.

parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT

Foo

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file name

required named arguments:
  -i INPUT, --input INPUT
                        Input file name

나는 같은 문제를 겪고있다. 나는 당신에게 해결책을 시도했습니다. 새 그룹에 인수를 추가하지만 그 후에는 코드가 작동하지 않는 것 같습니다. 모든 솔루션을 주시면 감사하겠습니다. - 내 코드 링크 pastebin.com/PvC2aujz
Zarar 마흐무드

1
@ZararMahmud : 코드의 24 행에 빈 인수를 전달합니다. parser.parse_args([])대신 parser.parse_args()인수없이 sys.argv의 내용을 캡처하십시오. 인수
Devin

@poke : 좋은 해결책! 그러나 상호 배타적 그룹이 필요한 경우 도움이되지 않거나 아무것도 누락 되었습니까?
판사


79

선택 사항 전에 필요한 인수를 나열하는 것을 선호하기 때문에 다음을 통해 해킹합니다.

    parser = argparse.ArgumentParser()
    parser._action_groups.pop()
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    required.add_argument('--required_arg', required=True)
    optional.add_argument('--optional_arg')
    return parser.parse_args()

그리고이 출력 :

usage: main.py [-h] [--required_arg REQUIRED_ARG]
               [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  --optional_arg OPTIONAL_ARG

선택적 인수 그룹에 '도움말'이 표시되지 않고 살 수 있습니다.


3
이것이 실제로 argparse가 필요에 따라 인수를 처리하도록 강제합니까?
Anthony

6
인수를 추가 할 때 여전히 '필수'인수를 설정해야한다고 생각합니다.
Karl Rosaen

정말 좋습니다.
Paul Cezanne

7
@Anthony-아니요. add_argument에 'required = True'가 필요하지 않습니다. 위의 답변은 인수 그룹화를 보여줍니다.
user2275693

47

@Karl Rosaen에서 시작

parser = argparse.ArgumentParser()
optional = parser._action_groups.pop() # Edited this line
required = parser.add_argument_group('required arguments')
# remove this line: optional = parser...
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
parser._action_groups.append(optional) # added this line
return parser.parse_args()

그리고이 출력 :

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  -h, --help                    show this help message and exit
  --optional_arg OPTIONAL_ARG

1
BTW, _action_group보호받는 회원 에게 접근하지 않고 접근 하는 방법 (방법)이 있습니까? 필자의 경우 이미 존재하는 (사용자 정의) 그룹에 인수를 추가해야합니다.
machin

대단하다. --help 항목을 두 번째 선택적 목록에 표시합니다.
Jeremy

참고 :이 답변은 노출 된 API를 중단합니다. 아래에서 Bryan_D의 답변을 확인하십시오 .
LOL

18

@RalphyZ를 기반으로 한 번 더

이것은 노출 된 API를 손상시키지 않습니다.

from argparse import ArgumentParser, SUPPRESS
# Disable default help
parser = ArgumentParser(add_help=False)
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')

# Add back help 
optional.add_argument(
    '-h',
    '--help',
    action='help',
    default=SUPPRESS,
    help='show this help message and exit'
)
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')

위와 동일하게 표시되며 이후 버전에서도 살아남 아야합니다.

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  -h, --help                    show this help message and exit
  --optional_arg OPTIONAL_ARG

RalphyZ의 답변이 노출 된 API를 어떻게 깨뜨리는 지 설명 할 수 있습니까?
jeremysprofile

5
_action_groups내부 전용입니다. 따라서 버전간에 호환성이 보장되지 않습니다.
Bryan_D
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.