argparse — 커맨드라인 옵션·인자·서브커맨드 파서

argparse — 커맨드라인 옵션·인자·서브커맨드 파서 (Parser for command-line options, arguments and subcommands)

argparse 모듈은 사용자 친화적인 커맨드라인 인터페이스를 쉽게 만들게 해 줘요. 프로그램이 어떤 인자가 필요한지 정의하면, argparse가 sys.argv에서 그걸 파싱해 줘요. help와 usage 메시지도 자동 생성하고, 사용자가 잘못된 인자를 주면 오류도 냅니다.

출처: Python 표준 라이브러리

본문

argparse 모듈은 사용자 친화적인 커맨드라인 인터페이스를 쉽게 작성하게 해 줘요. 프로그램이 필요로 하는 인자를 정의하면, argparse가 그걸 sys.argv에서 어떻게 파싱할지 알아서 처리해요. help와 usage 메시지도 자동으로 만들고, 사용자가 프로그램에 잘못된 인자를 주면 오류도 발생시켜요.

참고: argparse는 기본적인 커맨드라인 애플리케이션을 구현하는 데 권장되는 표준 라이브러리 모듈이지만, 커맨드라인 애플리케이션이 정확히 어떻게 동작해야 하는지에 대해 더 엄격한 요구사항이 있는 작성자에게는 충분한 수준의 제어를 제공하지 못할 수도 있어요. 애플리케이션이 요구하는 동작(예: interspersed 옵션과 위치 인자를 완전히 비활성화하거나, 다른 정의된 옵션에 해당하더라도 -로 시작하는 옵션 매개변수 값을 받아들이는 것)을 argparse가 지원하지 않을 때 고려할 대안에 대해서는 Choosing an argument parsing library를 참고하세요.

argparse의 커맨드라인 인터페이스 지원은 argparse.ArgumentParser 인스턴스를 중심으로 구성돼요. 이것은 인자 명세의 컨테이너이고, 파서 전체에 적용되는 옵션을 가져요.

parser = argparse.ArgumentParser(
                    prog='ProgramName',
                    description='What the program does',
                    epilog='Text at the bottom of help')

ArgumentParser.add_argument() 메서드는 개별 인자 명세를 파서에 붙여요. 위치 인자(positional), 값을 받는 옵션, 온/오프 플래그를 지원해요.

parser.add_argument('filename')           # positional argument
parser.add_argument('-c', '--count')      # option that takes a value
parser.add_argument('-v', '--verbose',
                    action='store_true')  # on/off flag

ArgumentParser.parse_args() 메서드는 파서를 실행하고 추출된 데이터를 argparse.Namespace 객체에 담아요.

args = parser.parse_args()
print(args.filename, args.count, args.verbose)

ArgumentParser 객체

class argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True, exit_on_error=True, *, suggest_on_error=False, color=True)

ArgumentParser 객체를 만들어요. 모든 매개변수는 키워드 인자로 넘겨야 해요. 각각에 대한 자세한 설명은 아래에 있지만, 짧게 정리하면 이래요.

  • prog — 프로그램의 이름 (기본값: __main__ 모듈 속성과 sys.argv[0]에서 생성)
  • usage — 프로그램 사용법을 설명하는 문자열 (기본값: 파서에 추가된 인자들에서 생성)
  • description — 인자 help 앞에 표시할 텍스트 (기본값: 없음)
  • epilog — 인자 help 뒤에 표시할 텍스트 (기본값: 없음)
  • parents — 그 인자들도 포함해야 할 ArgumentParser 객체의 리스트
  • formatter_class — help 출력을 커스터마이즈하는 클래스
  • prefix_chars — 선택 인자를 접두사로 하는 문자 집합 (기본값: -)
  • fromfile_prefix_chars — 추가 인자를 읽을 파일의 접두사로 하는 문자 집합 (기본값: None)
  • argument_default — 인자의 전역 기본값 (기본값: None)
  • conflict_handler — 충돌하는 선택적 인자를 해결하는 전략 (보통 불필요)
  • add_help — 파서에 -h/--help 옵션을 추가 (기본값: True)
  • allow_abbrev — 모호하지 않으면 긴 옵션의 약어를 허용 (기본값: True)
  • exit_on_error — 오류가 발생했을 때 ArgumentParser가 오류 정보로 종료할지 여부 (기본값: True)
  • suggest_on_error — 잘못 입력한 인자 선택과 서브파서 이름에 대한 추천을 활성화 (기본값: False)
  • color — 컬러 출력 허용 (기본값: True)

버전 변경: 3.5에서 allow_abbrev 추가, 3.8에서 이전 버전의 allow_abbrev-vv-v -v로 묶는 짧은 플래그 그룹핑도 비활성화하던 점 수정, 3.9에서 exit_on_error 추가, 3.14에서 suggest_on_errorcolor 추가.

prog

기본적으로 ArgumentParser는 help 메시지에 표시할 프로그램 이름을 Python 인터프리터가 실행된 방식에 따라 계산해요.

  • 파일이 인자로 넘겨지면 sys.argv[0]의 기본 이름
  • 디렉토리나 zipfile이 인자로 넘겨지면 Python 인터프리터 이름 뒤에 sys.argv[0]
  • -m 옵션이 사용되면 Python 인터프리터 이름 뒤에 -m, 그 다음 모듈이나 패키지 이름

이 기본값은 거의 항상 바람직해요. help 메시지가 커맨드라인에서 프로그램을 호출할 때 쓰인 문자열과 일치하게 만들어 주니까요. 이 기본 동작을 바꾸려면 ArgumentParserprog= 인자로 다른 값을 주면 돼요.

>>> parser = argparse.ArgumentParser(prog='myprogram')
>>> parser.print_help()
usage: myprogram [-h]

options:
 -h, --help  show this help message and exit

프로그램 이름은 sys.argv[0], __main__ 모듈 속성, prog= 인자 중 어느 쪽에서 왔든, help 메시지에 %(prog)s 형식 지정자로 사용할 수 있어요.

>>> parser = argparse.ArgumentParser(prog='myprogram')
>>> parser.add_argument('--foo', help='foo of the %(prog)s program')
>>> parser.print_help()
usage: myprogram [-h] [--foo FOO]

options:
 -h, --help  show this help message and exit
 --foo FOO   foo of the myprogram program

3.14 버전 변경: 기본 prog 값은 이제 항상 os.path.basename(sys.argv[0])이 아니라, __main__이 실제로 어떻게 실행됐는지를 반영해요.

usage

기본적으로 ArgumentParser는 usage 메시지를 자신이 담고 있는 인자들에서 계산해요. 기본 메시지는 usage= 키워드 인자로 재정의할 수 있어요.

>>> parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
>>> parser.add_argument('--foo', nargs='?', help='foo help')
>>> parser.add_argument('bar', nargs='+', help='bar help')
>>> parser.print_help()
usage: PROG [options]

positional arguments:
 bar          bar help

options:
 -h, --help   show this help message and exit
 --foo [FOO]  foo help

%(prog)s 형식 지정자로 usage 메시지에 프로그램 이름을 채울 수 있어요. 메인 파서에 커스텀 usage 메시지를 지정했다면, 서브파서 전체에서 일관된 명령 접두사와 usage 정보를 보장하기 위해 add_subparsers()prog 인자를, add_parser()progusage 인자를 넘기는 것도 고려할 만해요.

description

ArgumentParser 생성자 호출의 대부분은 description= 키워드 인자를 써요. 이 인자는 프로그램이 무엇을 하고 어떻게 동작하는지에 대한 간단한 설명을 줘요. help 메시지에서 description은 커맨드라인 usage 문자열과 각 인자의 help 메시지 사이에 표시돼요. 기본적으로 description은 주어진 공간에 맞게 줄바꿈돼요. 이 동작을 바꾸려면 formatter_class 인자를 보세요.

epilog

일부 프로그램은 인자의 설명 뒤에 프로그램에 대한 추가 설명을 표시하고 싶어해요. 그런 텍스트는 ArgumentParserepilog= 인자로 지정할 수 있어요.

>>> parser = argparse.ArgumentParser(
...     description='A foo that bars',
...     epilog="And that's how you'd foo a bar")
>>> parser.print_help()
usage: argparse.py [-h]

A foo that bars

options:
 -h, --help  show this help message and exit

And that's how you'd foo a bar

description 인자와 마찬가지로 epilog= 텍스트도 기본적으로 줄바꿈되지만, ArgumentParserformatter_class 인자로 조정할 수 있어요.

parents

여러 파서가 공통된 인자 집합을 공유할 때가 있어요. 그런 인자 정의를 반복하는 대신, 공유 인자를 모두 가진 단일 파서를 만들고 ArgumentParserparents= 인자로 넘길 수 있어요. parents= 인자는 ArgumentParser 객체들의 리스트를 받고, 그들로부터 모든 위치 인자와 선택 인자 action을 모아서 생성 중인 ArgumentParser 객체에 추가해요.

>>> parent_parser = argparse.ArgumentParser(add_help=False)
>>> parent_parser.add_argument('--parent', type=int)

>>> foo_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> foo_parser.add_argument('foo')
>>> foo_parser.parse_args(['--parent', '2', 'XXX'])
Namespace(foo='XXX', parent=2)

>>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> bar_parser.add_argument('--bar')
>>> bar_parser.parse_args(['--bar', 'YYY'])
Namespace(bar='YYY', parent=None)

대부분의 부모 파서는 add_help=False를 지정한다는 점에 유의하세요. 그렇지 않으면 ArgumentParser-h/--help 옵션을 두 개(부모에 하나, 자식에 하나) 보게 되어 오류를 발생시켜요.

참고: 파서들을 parents=로 넘기기 전에 반드시 완전히 초기화해야 해요. 자식 파서를 만든 뒤 부모 파서를 바꿔도 그 변경은 자식에 반영되지 않아요.

formatter_class

ArgumentParser 객체는 대체 포맷팅 클래스를 지정해 help 포맷을 커스터마이즈하게 해 줘요. 현재 네 가지 클래스가 있어요.

  • class argparse.RawDescriptionHelpFormatter
  • class argparse.RawTextHelpFormatter
  • class argparse.ArgumentDefaultsHelpFormatter
  • class argparse.MetavarTypeHelpFormatter

RawDescriptionHelpFormatterRawTextHelpFormatter는 텍스트 설명이 어떻게 표시되는지 더 많이 제어하게 해 줘요.

기본적으로 ArgumentParser 객체는 커맨드라인 help 메시지에서 description과 epilog 텍스트를 줄바꿈해요.

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     description='''this description
...         was indented weird
...             but that is okay''',
...     epilog='''
...             likewise for this epilog whose whitespace will
...         be cleaned up and whose words will be wrapped
...         across a couple lines''')
>>> parser.print_help()
usage: PROG [-h]

this description was indented weird but that is okay

options:
 -h, --help  show this help message and exit

likewise for this epilog whose whitespace will be cleaned up and whose words
will be wrapped across a couple lines

formatter_class=RawDescriptionHelpFormatter를 넘기면 description과 epilog가 이미 올바르게 포맷됐다고 보고 줄바꿈하지 않아요.

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.RawDescriptionHelpFormatter,
...     description=textwrap.dedent('''\
...         Please do not mess up this text!
...         --------------------------------
...             I have indented it
...             exactly the way
...             I want it
...         '''))
>>> parser.print_help()
usage: PROG [-h]

Please do not mess up this text!
--------------------------------
   I have indented it
   exactly the way
   I want it

options:
 -h, --help  show this help message and exit

RawTextHelpFormatter는 인자 설명을 포함한 모든 종류의 help 텍스트에서 공백을 유지해요. 다만 여러 개의 줄바꿈은 하나로 치환돼요. 여러 빈 줄을 유지하려면 줄바꿈 사이에 공백을 추가하세요.

ArgumentDefaultsHelpFormatter는 각 인자의 help 메시지에 기본값 정보를 자동으로 추가해요.

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
>>> parser.add_argument('--foo', type=int, default=42, help='FOO!')
>>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
>>> parser.print_help()
usage: PROG [-h] [--foo FOO] [bar ...]

positional arguments:
 bar         BAR! (default: [1, 2, 3])

options:
 -h, --help  show this help message and exit
 --foo FOO   FOO! (default: 42)

MetavarTypeHelpFormatter는 각 인자의 값에 대한 표시 이름으로 (일반 포매터가 dest를 쓰는 대신) type 인자의 이름을 사용해요.

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.MetavarTypeHelpFormatter)
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', type=float)
>>> parser.print_help()
usage: PROG [-h] [--foo int] float

positional arguments:
  float

options:
  -h, --help  show this help message and exit
  --foo int

prefix_chars

대부분의 커맨드라인 옵션은 접두사로 -를 써요, 예: -f/--foo. +f/foo 같은 옵션처럼 다른 또는 추가 접두사 문자를 지원해야 하는 파서는 ArgumentParser 생성자에 prefix_chars= 인자로 지정할 수 있어요.

>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
>>> parser.add_argument('+f')
>>> parser.add_argument('++bar')
>>> parser.parse_args('+f X ++bar Y'.split())
Namespace(bar='Y', f='X')

prefix_chars=의 기본값은 '-'예요. -를 포함하지 않는 문자 집합을 주면 -f/--foo 옵션이 허용되지 않아요.

fromfile_prefix_chars

특히 긴 인자 목록을 다룰 때, 커맨드라인에 타이핑하는 대신 파일에 인자 목록을 두는 게 합리적일 수 있어요. ArgumentParser 생성자에 fromfile_prefix_chars= 인자(None이 아닌)를 주면, 지정한 문자로 시작하는 인자들은 파일로 취급돼서 그 파일이 담고 있는 인자들로 대체돼요. 예를 들면:

>>> with open('args.txt', 'w', encoding=sys.getfilesystemencoding()) as fp:
...     fp.write('-f\nbar')
...
>>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
>>> parser.add_argument('-f')
>>> parser.parse_args(['-f', 'foo', '@args.txt'])
Namespace(f='bar')

파일에서 읽은 인자는 기본적으로 한 줄에 하나여야 하고(convert_arg_line_to_args()도 참고), 커맨드라인에서 원래 파일을 참조하는 인자가 있던 바로 그 자리에 있는 것처럼 취급돼요. 그래서 위 예시의 ['-f', 'foo', '@args.txt']['-f', 'foo', '-f', 'bar']와 동등한 것으로 간주돼요.

참고: 각 줄은 단일 인자로 취급되므로, 빈 줄은 빈 문자열('')로 읽혀요. ArgumentParser는 인자 파일을 읽을 때 filesystem encoding과 error handler를 사용해요.

fromfile_prefix_chars=의 기본값은 None으로, 인자가 파일 참조로 취급되지 않음을 뜻해요.

3.12 버전 변경: ArgumentParser가 인자 파일을 읽을 때 인코딩과 errors를 기본값(예: locale.getpreferredencoding(False)"strict")에서 filesystem encoding과 error handler로 바꿨어요. Windows에서는 인자 파일을 ANSI Codepage 대신 UTF-8로 인코딩해야 해요.

argument_default

일반적으로 인자 기본값은 add_argument()default를 넘기거나, 특정 이름-값 쌍으로 set_defaults() 메서드를 호출해서 지정해요. 하지만 때로는 파서 전체에 걸친 단일 기본값을 지정하는 게 유용할 수 있어요. 그것은 ArgumentParserargument_default= 키워드 인자를 넘기면 돼요. 예를 들어 parse_args() 호출 시 속성 생성이 전역적으로 억제되게 하려면 argument_default=SUPPRESS를 주면 돼요.

>>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar', nargs='?')
>>> parser.parse_args(['--foo', '1', 'BAR'])
Namespace(bar='BAR', foo='1')
>>> parser.parse_args([])
Namespace()

allow_abbrev

보통 ArgumentParserparse_args() 메서드에 인자 목록을 넘기면 긴 옵션의 약어를 인식해요. 이 기능은 allow_abbrevFalse로 설정해 비활성화할 수 있어요.

>>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False)
>>> parser.add_argument('--foobar', action='store_true')
>>> parser.add_argument('--foonley', action='store_false')
>>> parser.parse_args(['--foon'])
usage: PROG [-h] [--foobar] [--foonley]
PROG: error: unrecognized arguments: --foon

3.5 버전에서 추가.

conflict_handler

ArgumentParser 객체는 같은 옵션 문자열을 가진 두 action을 허용하지 않아요. 기본적으로 이미 사용 중인 옵션 문자열로 인자를 만들려고 하면 예외를 발생시켜요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo', help='old foo help')
>>> parser.add_argument('--foo', help='new foo help')
Traceback (most recent call last):
 ..
ArgumentError: argument --foo: conflicting option string(s): --foo

때로는(예: parents를 쓸 때) 같은 옵션 문자열을 가진 기존 인자를 그냥 덮어쓰는 게 유용할 수 있어요. 이 동작을 원하면 ArgumentParserconflict_handler= 인자에 'resolve' 값을 줄 수 있어요.

>>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
>>> parser.add_argument('-f', '--foo', help='old foo help')
>>> parser.add_argument('--foo', help='new foo help')
>>> parser.print_help()
usage: PROG [-h] [-f FOO] [--foo FOO]

options:
 -h, --help  show this help message and exit
 -f FOO      old foo help
 --foo FOO   new foo help

ArgumentParser 객체는 옵션 문자열이 모두 재정의됐을 때만 action을 제거해요. 그래서 위 예시에서 옛 -f/--foo action은 --foo 옵션 문자열만 재정의됐으므로 -f action으로 유지돼요.

add_help

기본적으로 ArgumentParser 객체는 파서의 help 메시지를 표시하는 옵션을 추가해요. 커맨드라인에 -h--help가 주어지면 ArgumentParser help가 출력돼요. 때때로 이 help 옵션 추가를 비활성화하는 게 유용할 수 있는데, ArgumentParseradd_help= 인자로 False를 넘기면 돼요.

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> parser.add_argument('--foo', help='foo help')
>>> parser.print_help()
usage: PROG [--foo FOO]

options:
 --foo FOO  foo help

help 옵션은 보통 -h/--help예요. 예외는 prefix_chars=가 지정되고 -를 포함하지 않을 때인데, 그 경우 -h--help가 유효한 옵션이 아니에요. 그 경우 prefix_chars의 첫 번째 문자가 help 옵션의 접두사로 쓰여요.

>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/')
>>> parser.print_help()
usage: PROG [+h]

options:
  +h, ++help  show this help message and exit

exit_on_error

보통 ArgumentParserparse_args() 메서드에 잘못된 인자 목록을 넘기면 sys.stderr에 메시지를 출력하고 종료 코드 2로 종료해요. 오류를 직접 잡고 싶다면 exit_on_errorFalse로 설정해 이 기능을 켤 수 있어요.

>>> parser = argparse.ArgumentParser(exit_on_error=False)
>>> parser.add_argument('--integers', type=int)
_StoreAction(option_strings=['--integers'], dest='integers', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> try:
...     parser.parse_args('--integers a'.split())
... except argparse.ArgumentError:
...     print('Catching an argumentError')
...
Catching an argumentError

3.9 버전에서 추가.

suggest_on_error

기본적으로 사용자가 잘못된 인자 선택이나 서브파서 이름을 주면 ArgumentParser는 오류 정보로 종료하면서 오류 메시지의 일부로 허용되는 인자 선택(지정된 경우)이나 서브파서 이름을 나열해요. 잘못 입력한 인자 선택과 서브파서 이름에 대한 추천을 활성화하려면 suggest_on_errorTrue로 설정하면 돼요. 단, 지정된 choices가 문자열일 때의 인자에만 적용된다는 점에 유의하세요.

>>> parser = argparse.ArgumentParser(suggest_on_error=True)
>>> parser.add_argument('--action', choices=['debug', 'dryrun'])
>>> parser.parse_args(['--action', 'debugg'])
usage: tester.py [-h] [--action {debug,dryrun}]
tester.py: error: argument --action: invalid choice: 'debugg', maybe you meant 'debug'? (choose from debug, dryrun)

구버전 Python과 호환되는 코드를 쓰면서 사용 가능할 때 suggest_on_error를 써 보려면, 키워드 인자 대신 파서 초기화 후 속성으로 설정해도 돼요.

>>> parser = argparse.ArgumentParser(description='Process some integers.')
>>> parser.suggest_on_error = True

3.14 버전에서 추가.

color

기본적으로 help 메시지는 ANSI 이스케이프 시퀀스로 컬러 출력돼요. 평문 help 메시지를 원하면 로컬 환경에서, 또는 colorFalse로 설정해 인자 파서 자체에서 비활성화할 수 있어요.

>>> parser = argparse.ArgumentParser(description='Process some integers.',
...                                  color=False)
>>> parser.add_argument('--action', choices=['sum', 'max'])
>>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
...                     help='an integer for the accumulator')
>>> parser.parse_args(['--help'])

color=True일 때 컬러 출력은 환경 변수와 터미널 기능 모두에 의존한다는 점을 기억하세요. 하지만 color=FalseFORCE_COLOR 같은 환경 변수가 설정돼 있어도 컬러 출력이 항상 비활성화돼요.

참고: stderr를 파일로 리다이렉트할 때 오류 메시지에 컬러 코드가 포함돼요. 이를 피하려면 NO_COLOR 또는 PYTHON_COLORS 환경 변수를 설정하세요 (예: NO_COLOR=1 python script.py 2> errors.txt).

3.14 버전에서 추가.

add_argument() 메서드

ArgumentParser.add_argument(name or flags..., *[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest][, deprecated])

단일 커맨드라인 인자가 어떻게 파싱돼야 하는지 정의해요. 각 매개변수는 아래에서 자세히 설명하지만, 짧게 정리하면 이래요.

  • name or flags — 이름이나 옵션 문자열의 리스트, 예: 'foo' 또는 '-f', '--foo'.
  • action — 커맨드라인에서 이 인자를 만났을 때 취할 동작의 기본 유형.
  • nargs — 소비해야 하는 커맨드라인 인자의 수.
  • const — 일부 action과 nargs 선택에 필요한 상수 값.
  • default — 인자가 커맨드라인에 없고 namespace 객체에도 없을 때 만들어지는 값.
  • type — 커맨드라인 인자가 변환돼야 할 타입.
  • choices — 인자에 허용되는 값들의 시퀀스.
  • required — 커맨드라인 옵션을 생략할 수 있는지 여부 (선택 인자에만 해당).
  • help — 인자가 무엇을 하는지에 대한 간단한 설명.
  • metavar — usage 메시지에서 인자의 이름.
  • destparse_args()가 반환하는 객체에 추가될 속성의 이름.
  • deprecated — 인자 사용이 폐기됐는지 여부.

이 메서드는 인자를 나타내는 Action 객체를 반환해요.

name or flags

add_argument() 메서드는 -f/--foo 같은 선택 인자인지, 파일 이름 리스트 같은 위치 인자인지 알아야 해요. 그래서 add_argument()에 넘기는 첫 인자는 플래그들의 시리즈거나, 단순한 인자 이름이어야 해요.

>>> parser.add_argument('-f', '--foo')   # selective: optional arg
>>> parser.add_argument('bar')           # positional arg

parse_args()가 호출되면 선택 인자는 - 접두사로 식별되고, 나머지 인자는 위치 인자로 간주돼요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args(['BAR'])
Namespace(bar='BAR', foo=None)
>>> parser.parse_args(['BAR', '--foo', 'FOO'])
Namespace(bar='BAR', foo='FOO')
>>> parser.parse_args(['--foo', 'FOO'])
usage: PROG [-h] [-f FOO] bar
PROG: error: the following arguments are required: bar

기본적으로 argparse는 인자의 내부 이름과 표시 이름을 자동으로 처리해요. 그래서 destmetavar 매개변수를 지정할 필요가 없어요. 선택 인자의 dest는 기본적으로 인자 이름에서 하이픈 -를 밑줄 _로 바꾼 값이고, metavar는 기본적으로 대문자화된 이름이에요. 예를 들면:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo-bar')
>>> parser.parse_args(['--foo-bar', 'FOO-BAR'])
Namespace(foo_bar='FOO-BAR')

action

ArgumentParser 객체는 커맨드라인 인자를 action과 연결해요. 대부분의 action은 단순히 parse_args()가 반환하는 객체에 속성을 추가해요. action 키워드 인자는 커맨드라인 인자를 어떻게 처리할지 지정해요. 제공되는 action들은 이래요.

  • 'store' — 인자의 값을 그냥 저장해요. 기본 action이에요.
  • 'store_const'const 키워드 인자가 지정한 값을 저장해요. const 키워드 인자의 기본값은 None이라는 점에 유의하세요. 'store_const' action은 어떤 종류의 플래그를 지정하는 선택 인자에 가장 흔히 쓰여요.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
>>> parser.parse_args(['--foo'])
Namespace(foo=42)
  • 'store_true''store_false' — 각각 TrueFalse를 저장하는 'store_const'의 특수한 경우로, 기본값은 각각 FalseTrue예요.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('--bar', action='store_false')
>>> parser.add_argument('--baz', action='store_false')
>>> parser.parse_args('--foo --bar'.split())
Namespace(foo=True, bar=False, baz=True)
  • 'append' — 각 인자 값을 리스트에 추가해요. 옵션이 여러 번 지정되게 허용할 때 유용해요. 기본값이 비어 있지 않은 리스트라면, 파싱된 값은 기본 리스트의 요소들로 시작하고 커맨드라인의 값들은 그 뒤에 추가돼요.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append', default=['0'])
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['0', '1', '2'])
  • 'append_const'const 키워드 인자가 지정한 값을 리스트에 추가해요. const의 기본값은 None이에요. 여러 인자가 같은 리스트에 상수를 저장해야 할 때 보통 유용해요.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<class 'str'>, <class 'int'>])
  • 'extend' — 다중 값 인자의 각 항목을 리스트에 추가해요. 보통 nargs 키워드 인자 값 '+''*'와 함께 써요. nargsNone(기본값)이거나 '?'일 때는 인자 문자열의 각 문자가 리스트에 추가된다는 점에 유의하세요.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument("--foo", action="extend", nargs="+", type=str)
>>> parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"])
Namespace(foo=['f1', 'f2', 'f3', 'f4'])

3.8 버전에서 추가.

  • 'count' — 인자가 나타난 횟수를 세요. 예를 들어 상세 수준을 높일 때 유용해요.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--verbose', '-v', action='count', default=0)
>>> parser.parse_args(['-vvv'])
Namespace(verbose=3)

명시적으로 설정하지 않으면 기본값은 None이에요. 기본값이 0이 아닌 숫자면, 카운트는 0이 아니라 그 숫자에서 시작해요.

  • 'help' — 현재 파서의 모든 옵션에 대한 전체 help 메시지를 출력하고 종료해요. 기본적으로 help action이 파서에 자동 추가돼요.
  • 'version'add_argument() 호출에서 version= 키워드 인자를 기대하고, 호출되면 버전 정보를 출력하고 종료해요.
>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
>>> parser.parse_args(['--version'])
PROG 2.0

Action 서브클래스(예: BooleanOptionalAction)나 같은 인터페이스를 구현하는 다른 객체를 넘겨 임의의 action을 지정할 수도 있어요. 커맨드라인 인자를 소비하는 action(예: 'store', 'append', 'extend', 또는 0이 아닌 nargs를 가진 커스텀 action)만 위치 인자에 쓸 수 있어요.

커스텀 action을 만드는 권장 방법은 Action을 확장해서 __call__() 메서드를, 선택적으로 __init__()format_usage() 메서드를 오버라이드하는 거예요. register() 메서드로 커스텀 action을 등록하고 등록된 이름으로 참조할 수도 있어요.

커스텀 action 예시:

>>> class FooAction(argparse.Action):
...     def __init__(self, option_strings, dest, nargs=None, **kwargs):
...         if nargs is not None:
...             raise ValueError("nargs not allowed")
...         super().__init__(option_strings, dest, **kwargs)
...     def __call__(self, parser, namespace, values, option_string=None):
...         print('%r %r %r' % (namespace, values, option_string))
...         setattr(namespace, self.dest, values)
...
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action=FooAction)
>>> parser.add_argument('bar', action=FooAction)
>>> args = parser.parse_args('1 --foo 2'.split())
Namespace(bar=None, foo=None) '1' None
Namespace(bar='1', foo=None) '2' '--foo'
>>> args
Namespace(bar='1', foo='2')

자세한 내용은 Action을 보세요.

nargs

ArgumentParser 객체는 보통 단일 커맨드라인 인자를 단일 action과 연결해요. nargs 키워드 인자는 서로 다른 개수의 커맨드라인 인자를 단일 action과 연결해요. 지원되는 값은 이래요.

  • N (정수) — 커맨드라인에서 N개의 인자를 모아 리스트로 만듭니다.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs=2)
>>> parser.add_argument('bar', nargs=1)
>>> parser.parse_args('c --foo a b'.split())
Namespace(bar=['c'], foo=['a', 'b'])

nargs=1은 한 항목의 리스트를 만든다는 점에 유의하세요. 항목이 그 자체로 만들어지는 기본값과는 달라요.

  • '?' — 가능하면 커맨드라인에서 하나의 인자를 소비해 단일 항목으로 만듭니다. 커맨드라인 인자가 없으면 default의 값이 만들어져요. 선택 인자에는 추가 케이스가 있어요 — 옵션 문자열은 있지만 뒤에 커맨드라인 인자가 없을 때. 그 경우 const의 값이 만들어져요.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='?', const='c', default='d')
>>> parser.add_argument('bar', nargs='?', default='d')
>>> parser.parse_args(['XX', '--foo', 'YY'])
Namespace(bar='XX', foo='YY')
>>> parser.parse_args(['XX', '--foo'])
Namespace(bar='XX', foo='c')
>>> parser.parse_args([])
Namespace(bar='d', foo='d')

nargs='?'의 가장 흔한 용도 중 하나는 선택적인 입력·출력 파일을 허용하는 것이에요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', nargs='?')
>>> parser.add_argument('outfile', nargs='?')
>>> parser.parse_args(['input.txt', 'output.txt'])
Namespace(infile='input.txt', outfile='output.txt')
>>> parser.parse_args(['input.txt'])
Namespace(infile='input.txt', outfile=None)
  • '*' — 존재하는 모든 커맨드라인 인자를 리스트로 모읍니다. nargs='*'를 가진 위치 인자가 두 개 이상인 건 일반적으로 의미가 없지만, nargs='*'를 가진 선택 인자가 여러 개인 건 가능해요.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='*')
>>> parser.add_argument('--bar', nargs='*')
>>> parser.add_argument('baz', nargs='*')
>>> parser.parse_args('a b --foo x y --bar 1 2'.split())
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
  • '+''*'와 마찬가지로 존재하는 모든 커맨드라인 인자를 리스트로 모읍니다. 추가로, 최소한 하나의 커맨드라인 인자가 없으면 오류 메시지가 생성돼요.
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', nargs='+')
>>> parser.parse_args(['a', 'b'])
Namespace(foo=['a', 'b'])
>>> parser.parse_args([])
usage: PROG [-h] foo [foo ...]
PROG: error: the following arguments are required: foo

nargs 키워드 인자를 제공하지 않으면 소비되는 인자의 수는 action이 결정해요. 일반적으로 단일 커맨드라인 인자가 소비되고 단일 항목(리스트 아님)이 만들어져요. 커맨드라인 인자를 소비하지 않는 action(예: 'store_const')은 nargs=0으로 설정돼요.

const

add_argument()const 인자는 커맨드라인에서 읽지 않지만 다양한 ArgumentParser action에 필요한 상수 값을 담는 데 쓰여요. 가장 흔한 두 가지 용도는:

  • action='store_const' 또는 action='append_const'add_argument()를 호출할 때. 이 action들은 parse_args()가 반환하는 객체의 속성 중 하나에 const 값을 추가해요. add_argument()const를 제공하지 않으면 기본값 None을 받아요.
  • 옵션 문자열(예: -f 또는 --foo)과 nargs='?'add_argument()를 호출할 때. 이렇게 하면 뒤에 커맨드라인 인자가 0개 또는 1개 따라올 수 있는 선택 인자가 만들어져요. 커맨드라인을 파싱할 때 옵션 문자열 뒤에 커맨드라인 인자가 없으면 const의 값이 사용돼요.

3.11 버전 변경: action='append_const'action='store_const'를 포함해 기본값이 const=None이에요.

default

모든 선택 인자와 일부 위치 인자는 커맨드라인에서 생략될 수 있어요. 기본값이 Noneadd_argument()default 키워드 인자는 커맨드라인 인자가 없을 때 사용할 값을 지정해요. 선택 인자의 경우, 옵션 문자열이 커맨드라인에 없었을 때 기본값이 사용돼요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
Namespace(foo=42)

대상 namespace에 이미 속성이 설정돼 있다면, action 기본값이 그것을 덮어쓰지 않아요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args([], namespace=argparse.Namespace(foo=101))
Namespace(foo=101)

기본값이 문자열이면 파서는 그 값을 커맨드라인 인자인 것처럼 파싱해요. 특히 Namespace 반환값에 속성을 설정하기 전에 type 변환 인자(제공된 경우)를 적용해요. 그렇지 않으면 파서는 값을 그대로 사용해요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--length', default='10', type=int)
>>> parser.add_argument('--width', default=10.5, type=int)
>>> parser.parse_args()
Namespace(length=10, width=10.5)

nargs? 또는 *인 위치 인자의 경우, 커맨드라인 인자가 없을 때 기본값이 사용돼요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)

nargs='*'는 제공된 값들을 리스트로 모으므로, 없는 위치 인자는 빈 리스트([])를 산출해요. None이 아닌 기본값만 이를 재정의해요(그래서 default=None은 여전히 []를 줘요).

필수 인자에 대해서는 기본값이 무시돼요. 예를 들어 nargs?이나 *가 아닌 위치 인자나 required=True로 표시된 선택 인자에 적용돼요.

default=argparse.SUPPRESS를 제공하면 커맨드라인 인자가 없을 때 속성이 추가되지 않아요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')

type

기본적으로 파서는 커맨드라인 인자를 단순 문자열로 읽어요. 하지만 커맨드라인 문자열을 floatint 같은 다른 타입으로 해석해야 하는 경우가 꽤 흔해요. add_argument()type 키워드는 필요한 타입 검사와 변환을 모두 수행하게 해 줘요. type 키워드를 default 키워드와 함께 쓰면, 타입 변환기는 기본값이 문자열일 때만 적용돼요.

type의 인자는 단일 문자열을 받는 callable이거나 등록된 타입의 이름(register() 참고)일 수 있어요. 함수가 ArgumentTypeError, TypeError, 또는 ValueError를 발생시키면 예외가 잡히고 잘 포맷된 오류 메시지가 표시돼요. 다른 예외 타입은 처리되지 않아요.

일반적인 내장 타입과 함수를 타입 변환기로 쓸 수 있어요.

import argparse
import pathlib

parser = argparse.ArgumentParser()
parser.add_argument('count', type=int)
parser.add_argument('distance', type=float)
parser.add_argument('street', type=ascii)
parser.add_argument('code_point', type=ord)
parser.add_argument('datapath', type=pathlib.Path)

사용자 정의 함수도 쓸 수 있어요.

>>> def hyphenated(string):
...     return '-'.join([word[:4] for word in string.casefold().split()])
...
>>> parser = argparse.ArgumentParser()
>>> _ = parser.add_argument('short_title', type=hyphenated)
>>> parser.parse_args(['"The Tale of Two Cities"'])
Namespace(short_title='"the-tale-of-two-citi')

bool() 함수는 타입 변환기로 권장되지 않아요. 그저 빈 문자열을 False, 비어 있지 않은 문자열을 True로 바꿀 뿐이에요. 보통 원하는 게 아니죠.

>>> parser = argparse.ArgumentParser()
>>> _ = parser.add_argument('--verbose', type=bool)
>>> parser.parse_args(['--verbose', 'False'])
Namespace(verbose=True)

일반적인 대안으로는 BooleanOptionalAction이나 action='store_true'가 있어요.

일반적으로 type 키워드는 세 가지 지원되는 예외 중 하나만 발생시킬 수 있는 단순한 변환에만 사용해야 해요. 더 흥미로운 오류 처리나 리소스 관리를 필요로 하는 것은 인자가 파싱된 뒤에 후처리로 해야 해요. 예를 들어 JSON이나 YAML 변환은 type 키워드가 줄 수 있는 것보다 더 나은 보고가 필요한 복잡한 오류 케이스를 가져요. JSONDecodeError는 잘 포맷되지 않고 FileNotFoundError 예외는 전혀 처리되지 않을 거예요. FileTypetype 키워드와 함께 쓰면 한계가 있어요. 한 인자가 FileType을 쓰고 다음 인자가 실패하면 오류가 보고되지만 파일은 자동으로 닫히지 않아요. 그 경우 파서가 실행된 뒤에 with 문으로 파일을 관리하는 게 더 낫겠죠. 고정된 값 집합에 대해 단순히 검사하는 타입 검사기라면 choices 키워드를 고려해 보세요.

choices

일부 커맨드라인 인자는 제한된 값 집합에서 선택돼야 해요. 이것들은 add_argument()choices 키워드 인자로 시퀀스 객체를 넘겨서 처리할 수 있어요. 커맨드라인이 파싱될 때 인자 값이 검사되고, 허용되는 값 중 하나가 아니면 오류 메시지가 표시돼요.

>>> parser = argparse.ArgumentParser(prog='game.py')
>>> parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
>>> parser.parse_args(['rock'])
Namespace(move='rock')
>>> parser.parse_args(['fire'])
usage: game.py [-h] {rock,paper,scissors}
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock',
'paper', 'scissors')

choices 값으로 어떤 시퀀스든 넘길 수 있으므로 list 객체, tuple 객체, 커스텀 시퀀스가 모두 지원돼요. enum.Enum 사용은 usage, help, 오류 메시지에서 그 표시를 제어하기 어려워 권장되지 않아요. choices는 타입 변환이 수행된 뒤에 검사되므로 choices의 객체는 지정된 타입과 일치해야 해요. choices를 사용자 친화적으로 유지하려면 값을 변환·포맷하는 커스텀 타입 래퍼를 고려하거나, type을 생략하고 애플리케이션 코드에서 변환을 처리하세요. 포맷된 choices는 보통 dest에서 파생되는 기본 metavar를 재정의해요. 사용자는 dest 매개변수를 보지 못하므로 보통 원하는 동작이에요. 이 표시가 마음에 들지 않으면(아마 choices가 많아서) 명시적인 metavar를 지정하세요.

required

일반적으로 argparse 모듈은 -f/--bar 같은 플래그가 커맨드라인에서 항상 생략될 수 있는 선택 인자를 나타낸다고 가정해요. 옵션을 필수로 만들려면 add_argument()required= 키워드 인자에 True를 지정할 수 있어요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
usage: [-h] --foo FOO
: error: the following arguments are required: --foo

예시에서 보듯, 옵션이 required로 표시되면 커맨드라인에 그 옵션이 없을 때 parse_args()가 오류를 보고해요.

참고: 필수 옵션은 사용자가 옵션은 선택적일 거라 기대하므로 일반적으로 나쁜 형태로 간주돼요. 가능하면 피해야 해요.

help

help 값은 인자에 대한 간단한 설명을 담은 문자열이에요. 사용자가 help를 요청하면(보통 커맨드라인에서 -h/--help 사용) 이 help 설명이 각 인자와 함께 표시돼요. help 문자열은 프로그램 이름이나 인자 기본값 같은 것을 반복하지 않도록 다양한 형식 지정자를 포함할 수 있어요. 사용 가능한 지정자는 프로그램 이름 %(prog)s와 대부분의 add_argument() 키워드 인자, 예: %(default)s, %(type)s 등을 포함해요.

>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('bar', nargs='?', type=int, default=42,
...                     help='the bar to %(prog)s (default: %(default)s)')
>>> parser.print_help()
usage: frobble [-h] [bar]

positional arguments:
 bar     the bar to frobble (default: 42)

options:
 -h, --help  show this help message and exit

help 문자열이 %-포맷팅을 지원하므로 help 문자열에 리터럴 %를 넣으려면 %%로 이스케이프해야 해요.

argparsehelp 값을 argparse.SUPPRESS로 설정해 특정 옵션의 help 항목을 숨기는 것을 지원해요.

>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', help=argparse.SUPPRESS)
>>> parser.print_help()
usage: frobble [-h]

options:
  -h, --help  show this help message and exit

metavar

ArgumentParser가 help 메시지를 생성할 때, 각 기대 인자를 어떻게든 참조해야 해요. 기본적으로 ArgumentParser 객체는 각 객체의 "이름"으로 dest 값을 사용해요. 위치 인자 action에서는 dest 값을 직접 사용하고, 선택 인자 action에서는 dest 값을 대문자화해요. 그래서 dest='bar'인 단일 위치 인자는 bar로, 단일 커맨드라인 인자가 따라와야 하는 선택 인자 --fooFOO로 참조돼요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo FOO] bar

positional arguments:
 bar

options:
 -h, --help  show this help message and exit
 --foo FOO

metavar로 대체 이름을 지정할 수 있어요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', metavar='YYY')
>>> parser.add_argument('bar', metavar='XXX')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo YYY] XXX

positional arguments:
 XXX

options:
 -h, --help  show this help message and exit
 --foo YYY

metavar는 표시 이름만 바꾼다는 점에 유의하세요 — parse_args() 객체의 속성 이름은 여전히 dest 값이 결정해요. nargs 값이 다르면 metavar가 여러 번 사용될 수 있어요. metavar에 튜플을 제공하면 각 인자마다 다른 표시를 지정해요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', nargs=2)
>>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
>>> parser.print_help()
usage: PROG [-h] [-x X X] [--foo bar baz]

options:
 -h, --help     show this help message and exit
 -x X X
 --foo bar baz

dest

대부분의 ArgumentParser action은 어떤 값을 parse_args()가 반환하는 객체의 속성으로 추가해요. 이 속성의 이름은 add_argument()dest 키워드 인자가 결정해요. 위치 인자 action의 경우 dest는 보통 add_argument()의 첫 번째 인자로 제공돼요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args(['XXX'])
Namespace(bar='XXX')

선택 인자 action의 경우 dest의 값은 보통 옵션 문자열에서 추론돼요. ArgumentParser는 첫 번째 긴 옵션 문자열을 가져와 초기 -- 문자열을 제거해 dest 값을 생성해요. 긴 옵션 문자열이 없으면 dest는 첫 번째 짧은 옵션 문자열에서 초기 - 문자를 제거해 파생돼요. 내부의 - 문자는 문자열이 유효한 속성 이름이 되도록 _ 문자로 변환돼요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-f', '--foo-bar', '--foo')
>>> parser.add_argument('-x', '-y')
>>> parser.parse_args('-f 1 -x 2'.split())
Namespace(foo_bar='1', x='2')
>>> parser.parse_args('--foo 1 -y 2'.split())
Namespace(foo_bar='1', x='2')

dest는 커스텀 속성 이름을 제공하게 해 줘요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar')
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')

여러 인자가 같은 dest를 공유할 수 있어요. 기본적으로 커맨드라인에서 주어진 그런 인자 중 마지막 값이 이겨요. 대신 action='append'를 사용해 모두의 값을 리스트로 모을 수 있어요. dest 이름이 아니라 충돌하는 옵션 문자열에 대해서는 conflict_handler를 보세요.

deprecated

프로젝트 수명 동안 일부 인자는 커맨드라인에서 제거해야 할 수 있어요. 제거하기 전에 사용자에게 인자가 폐기되고 제거될 것임을 알려야 해요. 기본값이 Falseadd_argument()deprecated 키워드 인자는 인자가 폐기되고 미래에 제거될지 여부를 지정해요. 인자에 대해 deprecatedTrue면 인자가 사용될 때 sys.stderr에 경고가 출력돼요.

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='snake.py')
>>> parser.add_argument('--legs', default=0, type=int, deprecated=True)
>>> parser.parse_args([])
Namespace(legs=0)
>>> parser.parse_args(['--legs', '4'])
snake.py: warning: option '--legs' is deprecated
Namespace(legs=4)

3.13 버전에서 추가.

Action 클래스

Action 클래스는 커맨드라인에서 인자를 처리하는 callable을 반환하는 callable인 Action API를 구현해요. 이 API를 따르는 어떤 객체든 add_argument()action 매개변수로 넘길 수 있어요.

class argparse.Action(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)

Action 객체는 ArgumentParser가 커맨드라인의 하나 이상의 문자열에서 단일 인자를 파싱하는 데 필요한 정보를 나타내는 데 사용돼요. Action 클래스는 두 개의 위치 인자와, action 자체를 제외한 ArgumentParser.add_argument()에 전달된 모든 키워드 인자를 받아들여야 해요. Action의 인스턴스(또는 action 매개변수에 대한 어떤 callable의 반환값)는 dest, option_strings, default, type, required, help 등의 속성을 정의해야 해요. 이 속성이 정의되게 하는 가장 쉬운 방법은 Action.__init__()을 호출하는 거예요.

__call__(parser, namespace, values, option_string=None)

Action 인스턴스는 callable이어야 하므로 서브클래스는 네 개의 매개변수를 받아들여야 하는 __call__() 메서드를 오버라이드해야 해요.

  • parser — 이 action을 담고 있는 ArgumentParser 객체.
  • namespaceparse_args()가 반환할 Namespace 객체. 대부분의 action은 setattr()로 이 객체에 속성을 추가해요.
  • values — 타입 변환이 적용된 관련 커맨드라인 인자. 타입 변환은 add_argument()type 키워드 인자로 지정돼요.
  • option_string — 이 action을 호출하는 데 사용된 옵션 문자열. option_string 인자는 선택적이고, action이 위치 인자와 연결돼 있으면 없어요.

__call__() 메서드는 임의의 동작을 수행할 수 있지만, 보통 destvalues에 기반해 namespace에 속성을 설정해요.

format_usage()

Action 서브클래스는 인자를 받지 않고 프로그램의 usage를 출력할 때 사용될 문자열을 반환하는 format_usage() 메서드를 정의할 수 있어요. 그런 메서드가 제공되지 않으면 합리적인 기본값이 사용돼요.

class argparse.BooleanOptionalAction

양수와 음수 옵션을 가진 부울 플래그를 처리하기 위한 Action의 서브클래스예요. --foo 같은 단일 인자를 추가하면 자동으로 --foo--no-foo 옵션을 모두 만들고 각각 TrueFalse를 저장해요.

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action=argparse.BooleanOptionalAction)
>>> parser.parse_args(['--no-foo'])
Namespace(foo=False)

3.9 버전에서 추가.

parse_args() 메서드

ArgumentParser.parse_args(args=None, namespace=None)

인자 문자열을 객체로 변환하고 namespace의 속성으로 할당해요. 채워진 namespace를 반환해요.

이전의 add_argument() 호출이 정확히 어떤 객체가 만들어지고 어떻게 할당되는지 결정해요. args — 파싱할 문자열의 리스트. 기본값은 sys.argv에서 가져와요. namespace — 속성을 받을 객체. 기본값은 새 빈 Namespace 객체예요.

옵션 값 문법

parse_args() 메서드는 옵션의 값(값을 받는다면)을 지정하는 여러 방식을 지원해요. 가장 단순한 경우, 옵션과 그 값은 두 개의 분리된 인자로 전달돼요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('--foo')
>>> parser.parse_args(['-x', 'X'])
Namespace(foo=None, x='X')
>>> parser.parse_args(['--foo', 'FOO'])
Namespace(foo='FOO', x=None)

긴 옵션(한 문자보다 긴 이름의 옵션)의 경우 옵션과 값은 =로 구분해 단일 커맨드라인 인자로도 전달할 수 있어요.

>>> parser.parse_args(['--foo=FOO'])
Namespace(foo='FOO', x=None)

짧은 옵션(한 문자짜리 옵션)의 경우 옵션과 값은 연결할 수 있어요.

>>> parser.parse_args(['-xX'])
Namespace(foo=None, x='X')

여러 짧은 옵션은 마지막 옵션만(또는 아무것도) 값이 필요하면, 단일 - 접두사만 사용해 결합할 수 있어요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', action='store_true')
>>> parser.add_argument('-y', action='store_true')
>>> parser.add_argument('-z')
>>> parser.parse_args(['-xyzZ'])
Namespace(x=True, y=True, z='Z')

잘못된 인자

커맨드라인을 파싱하는 동안 parse_args()는 모호한 옵션, 잘못된 타입, 잘못된 옵션, 위치 인자의 잘못된 개수 등 다양한 오류를 검사해요. 그런 오류를 만나면 usage 메시지와 함께 오류를 출력하고 종료해요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', nargs='?')

>>> # invalid type
>>> parser.parse_args(['--foo', 'spam'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: argument --foo: invalid int value: 'spam'

>>> # invalid option
>>> parser.parse_args(['--bar'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: unrecognized arguments: --bar

>>> # wrong number of arguments
>>> parser.parse_args(['spam', 'badger'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: unrecognized arguments: badger

-를 포함하는 인자

parse_args() 메서드는 사용자가 분명히 실수했을 때마다 오류를 주려고 하지만, 어떤 상황은 본질적으로 모호해요. 예를 들어 커맨드라인 인자 -1은 옵션을 지정하려는 것일 수도, 위치 인자를 제공하려는 것일 수도 있어요. parse_args() 메서드는 여기서 조심해요. 위치 인자는 음수처럼 보이고 파서에 음수처럼 보이는 옵션이 없을 때만 -로 시작할 수 있어요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('foo', nargs='?')

>>> # no negative number options, so -1 is a positional argument
>>> parser.parse_args(['-x', '-1'])
Namespace(foo=None, x='-1')

>>> # no negative number options, so -1 and -5 are positional arguments
>>> parser.parse_args(['-x', '-1', '-5'])
Namespace(foo='-5', x='-1')

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-1', dest='one')
>>> parser.add_argument('foo', nargs='?')

>>> # negative number options present, so -1 is an option
>>> parser.parse_args(['-1', 'X'])
Namespace(foo=None, one='X')

>>> # negative number options present, so -2 is an option
>>> parser.parse_args(['-2'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: unrecognized arguments: -2

-로 시작해야 하고 음수처럼 보이지 않는 위치 인자가 있다면, 그 뒤의 모든 것이 위치 인자임을 parse_args()에 알려주는 의사 인자 '--'를 넣을 수 있어요.

>>> parser.parse_args(['--', '-f'])
Namespace(foo='-f', one=None)

3.14 버전 변경: 음수 일치가 과학 표기법의 숫자(-2.5e-6), 밑줄을 포함하는 숫자(-1_234.5), 복소수(-1.2e-3j)까지 확장됐어요.

인자 약어 (접두사 일치)

parse_args() 메서드는 기본적으로 약어가 모호하지 않을 때(접두사가 고유한 옵션과 일치할 때) 긴 옵션이 접두사로 약어화되는 것을 허용해요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-bacon')
>>> parser.add_argument('-badger')
>>> parser.parse_args('-bac MMM'.split())
Namespace(bacon='MMM', badger=None)
>>> parser.parse_args('-bad WOOD'.split())
Namespace(bacon=None, badger='WOOD')
>>> parser.parse_args('-ba BA'.split())
usage: PROG [-h] [-bacon BACON] [-badger BADGER]
PROG: error: ambiguous option: -ba could match -badger, -bacon

둘 이상의 옵션을 만들 수 있는 인자에 대해서는 오류가 발생해요. 이 기능은 allow_abbrevFalse로 설정해 비활성화할 수 있어요.

sys.argv 너머

때로는 ArgumentParsersys.argv 이외의 인자를 파싱하게 하는 게 유용할 수 있어요. parse_args()에 문자열 리스트를 넘기면 돼요. 인터랙티브 프롬프트에서 테스트할 때 유용해요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument(
...     'integers', metavar='int', type=int, choices=range(10),
...     nargs='+', help='an integer in the range 0..9')
>>> parser.add_argument(
...     '--sum', dest='accumulate', action='store_const', const=sum,
...     default=max, help='sum the integers (default: find the max)')
>>> parser.parse_args(['1', '2', '3', '4'])
Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
>>> parser.parse_args(['1', '2', '3', '4', '--sum'])
Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])

Namespace 객체

class argparse.Namespace

parse_args()가 속성을 담고 있는 객체를 만들어 반환하는 데 기본으로 사용하는 간단한 클래스예요. 이 클래스는 의도적으로 단순합니다. 읽을 수 있는 문자열 표현이 있는 object 서브클래스일 뿐이에요. 속성의 dict 같은 뷰를 선호한다면 표준 Python 관용구인 vars()를 사용할 수 있어요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

ArgumentParser가 새 Namespace 객체가 아니라 이미 존재하는 객체에 속성을 할당하게 하는 것도 유용할 수 있어요. namespace= 키워드 인자를 지정하면 돼요.

>>> class C:
...     pass
...
>>> c = C()
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
>>> c.foo
'BAR'

기타 유틸리티

서브커맨드 (Subcommands)

ArgumentParser.add_subparsers(*[, title][, description][, prog][, parser_class][, action][, dest][, required][, help][, metavar])

많은 프로그램이 기능을 여러 서브커맨드로 나누어요. 예를 들어 svn 프로그램은 svn checkout, svn update, svn commit 같은 서브커맨드를 호출할 수 있죠. 프로그램이 서로 다른 종류의 커맨드라인 인자를 요구하는 여러 기능을 수행할 때, 이렇게 기능을 나누는 게 특히 좋은 생각일 수 있어요. ArgumentParseradd_subparsers() 메서드로 이런 서브커맨드 생성을 지원해요.

매개변수 설명:

  • title — help 출력에서 서브파서 그룹의 제목; 기본값은 description이 제공되면 "subcommands", 아니면 위치 인자 쪽의 title을 사용
  • description — help 출력에서 서브파서 그룹의 설명; 기본값 None
  • prog — 서브커맨드 help와 함께 표시될 usage 정보; 기본값은 프로그램 이름과 서브파서 인자 앞의 위치 인자들
  • parser_class — 서브파서 인스턴스를 만드는 데 사용할 클래스; 기본값은 현재 파서의 클래스(예: ArgumentParser)
  • action — 커맨드라인에서 이 인자를 만났을 때 취할 동작의 기본 유형
  • dest — 서브커맨드 이름이 저장될 속성의 이름; 기본값 None으로 값이 저장되지 않음
  • required — 서브커맨드를 반드시 제공해야 하는지; 기본값 False (3.7에서 추가)
  • help — help 출력에서 서브파서 그룹의 help; 기본값 None
  • metavar — help에서 사용 가능한 서브커맨드를 표시하는 문자열; 기본값은 None으로 {cmd1, cmd2, ..} 형태로 표시

add_subparsers() 메서드는 보통 인자 없이 호출되고 특별한 action 객체를 반환해요. 이 객체는 명령 이름과 ArgumentParser 생성자 인자를 받아, 평소처럼 수정할 수 있는 ArgumentParser 객체를 반환하는 단일 메서드 add_parser()를 가져요.

예시 사용:

>>> # create the top-level parser
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', action='store_true', help='foo help')
>>> subparsers = parser.add_subparsers(help='subcommand help')
>>>
>>> # create the parser for the "a" command
>>> parser_a = subparsers.add_parser('a', help='a help')
>>> parser_a.add_argument('bar', type=int, help='bar help')
>>>
>>> # create the parser for the "b" command
>>> parser_b = subparsers.add_parser('b', help='b help')
>>> parser_b.add_argument('--baz', choices=('X', 'Y', 'Z'), help='baz help')
>>>
>>> # parse some argument lists
>>> parser.parse_args(['a', '12'])
Namespace(bar=12, foo=False)
>>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
Namespace(baz='Z', foo=True)

parse_args()가 반환하는 객체는 메인 파서와 커맨드라인이 선택한 서브파서에 대한 속성만 담는다는 점에 유의하세요 (다른 서브파서는 아님). 위 예시에서 a 명령이 지정되면 foobar 속성만 있고, b 명령이 지정되면 foobaz 속성만 있어요. 서브파서가 부모 파서와 같은 dest의 인자를 정의하면 둘은 단일 namespace 속성을 공유하므로 부모의 값이 유지되지 않아요. 둘 다 유지하려면 구별되는 dest 값을 주세요. 마찬가지로 서브파서에서 help 메시지를 요청하면 그 특정 파서의 help만 출력돼요. help 메시지에 부모 파서나 형제 파서 메시지는 포함되지 않아요. (각 서브커맨드의 help 메시지는 위처럼 add_parser()help= 인자를 주면 가능해요.)

>>> parser.parse_args(['--help'])
usage: PROG [-h] [--foo] {a,b} ...

positional arguments:
  {a,b}   subcommand help
    a     a help
    b     b help

options:
  -h, --help  show this help message and exit
  --foo   foo help

add_subparsers() 메서드는 titledescription 키워드 인자도 지원해요. 둘 중 하나가 있으면 서브파서의 명령들이 help 출력에서 자체 그룹으로 나타나요. 예를 들면:

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(title='subcommands',
...                                    description='valid subcommands',
...                                    help='additional help')
>>> subparsers.add_parser('foo')
>>> subparsers.add_parser('bar')
>>> parser.parse_args(['-h'])
usage:  [-h] {foo,bar} ...

options:
  -h, --help  show this help message and exit

subcommands:
  valid subcommands

  {foo,bar}   additional help

게다가 add_parser()는 여러 문자열이 같은 서브파서를 참조할 수 있게 하는 추가 aliases 인자를 지원해요. 이 예시는 svn처럼 cocheckout의 약칭으로 사용해요.

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()
>>> checkout = subparsers.add_parser('checkout', aliases=['co'])
>>> checkout.add_argument('foo')
>>> parser.parse_args(['co', 'bar'])
Namespace(foo='bar')

add_parser()는 서브파서를 폐기할 수 있게 하는 추가 deprecated 인자도 지원해요.

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='chicken.py')
>>> subparsers = parser.add_subparsers()
>>> run = subparsers.add_parser('run')
>>> fly = subparsers.add_parser('fly', deprecated=True)
>>> parser.parse_args(['fly'])
chicken.py: warning: command 'fly' is deprecated
Namespace()

3.13 버전에서 추가.

서브커맨드를 다루는 특히 효과적인 방법 하나는 add_subparsers() 메서드를 set_defaults() 호출과 결합해서, 각 서브파서가 자신이 실행해야 할 Python 함수를 알게 하는 거예요. 예를 들면:

>>> # subcommand functions
>>> def foo(args):
...     print(args.x * args.y)
...
>>> def bar(args):
...     print('((%s))' % args.z)
...
>>> # create the top-level parser
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(required=True)
>>>
>>> # create the parser for the "foo" command
>>> parser_foo = subparsers.add_parser('foo')
>>> parser_foo.add_argument('-x', type=int, default=1)
>>> parser_foo.add_argument('y', type=float)
>>> parser_foo.set_defaults(func=foo)
>>>
>>> # create the parser for the "bar" command
>>> parser_bar = subparsers.add_parser('bar')
>>> parser_bar.add_argument('z')
>>> parser_bar.set_defaults(func=bar)
>>>
>>> # parse the args and call whatever function was selected
>>> args = parser.parse_args('foo 1 -x 2'.split())
>>> args.func(args)
2.0
>>>
>>> args = parser.parse_args('bar XYZYX'.split())
>>> args.func(args)
((XYZYX))

이렇게 하면 parse_args()가 인자 파싱이 끝난 뒤 적절한 함수를 호출하는 일을 대신하게 할 수 있어요. 이렇게 함수를 action과 연결하는 게 각 서브파서의 서로 다른 action을 처리하는 가장 쉬운 방법이에요. 단, 호출된 서브파서의 이름을 확인해야 한다면 add_subparsers() 호출의 dest 키워드 인자가 동작해요.

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(dest='subparser_name')
>>> subparser1 = subparsers.add_parser('1')
>>> subparser1.add_argument('-x')
>>> subparser2 = subparsers.add_parser('2')
>>> subparser2.add_argument('y')
>>> parser.parse_args(['2', 'frobble'])
Namespace(subparser_name='2', y='frobble')

3.7 버전 변경: 새 required 키워드 전용 매개변수 추가. 3.14 버전 변경: 서브파서의 prog가 메인 파서의 커스텀 usage 메시지의 영향을 더 이상 받지 않게 됐어요.

FileType 객체

class argparse.FileType(mode='r', bufsize=-1, encoding=None, errors=None)

FileType 팩토리는 ArgumentParser.add_argument()type 인자에 넘길 수 있는 객체를 만들어요. FileType 객체를 타입으로 가진 인자는 커맨드라인 인자를 요청된 모드, 버퍼 크기, 인코딩, 오류 처리로 파일을 열어요(open() 함수 참고).

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--raw', type=argparse.FileType('wb', 0))
>>> parser.add_argument('out', type=argparse.FileType('w', encoding='UTF-8'))
>>> parser.parse_args(['--raw', 'raw.dat', 'file.txt'])
Namespace(out=<_io.TextIOWrapper name='file.txt' mode='w' encoding='UTF-8'>, raw=<_io.FileIO name='raw.dat' mode='wb'>)

FileType 객체는 의사 인자 '-'를 이해하고, 읽기가 가능한 FileType 객체에 대해서는 sys.stdin으로, 쓰기가 가능한 FileType 객체에 대해서는 sys.stdout으로 자동 변환해요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', type=argparse.FileType('r'))
>>> parser.parse_args(['-'])
Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)

참고: 한 인자가 FileType을 쓰고 다음 인자가 실패하면 오류가 보고되지만 파일은 자동으로 닫히지 않아요. 이는 출력 파일을 덮어쓸 수도 있어요. 이 경우 파서가 실행된 뒤에 with 문으로 파일을 관리하는 게 더 낫습니다.

3.4 버전 변경: encodingerrors 매개변수 추가. 3.14 버전부터 폐기.

인자 그룹 (Argument groups)

ArgumentParser.add_argument_group(title=None, description=None, *[, argument_default][, conflict_handler])

기본적으로 ArgumentParser는 help 메시지를 표시할 때 커맨드라인 인자를 "positional arguments"와 "options"로 그룹화해요. 기본 그룹보다 인자를 개념적으로 더 잘 그룹화할 수 있을 때 add_argument_group() 메서드로 그룹을 만들 수 있어요.

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> group = parser.add_argument_group('group')
>>> group.add_argument('--foo', help='foo help')
>>> group.add_argument('bar', help='bar help')
>>> parser.print_help()
usage: PROG [--foo FOO] bar

group:
  bar    bar help
  --foo FOO  foo help

add_argument_group() 메서드는 일반 ArgumentParser와 같은 add_argument() 메서드를 가진 인자 그룹 객체를 반환해요. 그룹에 인자를 추가하면 파서는 그것을 일반 인자처럼 취급하지만, help 메시지에서는 인자를 별도 그룹에 표시해요. add_argument_group() 메서드는 이 표시를 커스터마이즈하는 데 쓸 수 있는 titledescription 인자를 받아요.

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> group1 = parser.add_argument_group('group1', 'group1 description')
>>> group1.add_argument('foo', help='foo help')
>>> group2 = parser.add_argument_group('group2', 'group2 description')
>>> group2.add_argument('--bar', help='bar help')
>>> parser.print_help()
usage: PROG [--bar BAR] foo

group1:
  group1 description

  foo    foo help

group2:
  group2 description

  --bar BAR  bar help

선택적 키워드 전용 매개변수 argument_defaultconflict_handler는 인자 그룹의 동작을 더 세밀하게 제어하게 해 줘요. 이 매개변수들은 ArgumentParser 생성자에서와 같은 의미를 갖지만, 전체 파서가 아니라 인자 그룹에 특별히 적용돼요. 사용자 정의 그룹에 없는 인자는 평소의 "positional arguments"와 "optional arguments" 섹션으로 돌아간다는 점에 유의하세요. 각 인자 그룹 안에서 인자는 추가된 순서대로 help 출력에 표시돼요.

3.11 버전부터 폐기, 3.14 버전에서 제거: 인자 그룹에서 add_argument_group()을 호출하면 이제 예외가 발생해요. 이 중첩은 지원된 적이 없고, 종종 올바르게 동작하지 않았으며, 상속을 통해 의도치 않게 노출됐어요. 3.14 버전부터 폐기: add_argument_group()prefix_chars를 넘기는 것이 폐기됐어요.

상호 배제 (Mutual exclusion)

ArgumentParser.add_mutually_exclusive_group(required=False)

상호 배제 그룹을 만들어요. argparse는 상호 배제 그룹의 인자 중 하나만 커맨드라인에 존재하도록 확인해요.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_mutually_exclusive_group()
>>> group.add_argument('--foo', action='store_true')
>>> group.add_argument('--bar', action='store_false')
>>> parser.parse_args(['--foo'])
Namespace(bar=True, foo=True)
>>> parser.parse_args(['--foo', '--bar'])
usage: PROG [-h] [--foo | --bar]
PROG: error: argument --bar: not allowed with argument --foo

add_mutually_exclusive_group() 메서드는 required 인자도 받아, 상호 배제 인자 중 하나 이상이 필수임을 나타냅니다.

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_mutually_exclusive_group(required=True)
>>> group.add_argument('--foo', action='store_true')
>>> group.add_argument('--bar', action='store_false')
>>> parser.parse_args([])
usage: PROG [-h] (--foo | --bar)
PROG: error: one of the arguments --foo --bar is required

현재 상호 배제 인자 그룹은 add_argument_group()titledescription 인자를 지원하지 않는다는 점에 유의하세요. 하지만 상호 배제 그룹은 title과 description이 있는 인자 그룹에 추가할 수는 있어요. 예를 들면:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_argument_group('Group title', 'Group description')
>>> exclusive_group = group.add_mutually_exclusive_group(required=True)
>>> exclusive_group.add_argument('--foo', help='foo help')
>>> exclusive_group.add_argument('--bar', help='bar help')
>>> parser.print_help()
usage: PROG [-h] (--foo FOO | --bar BAR)

options:
  -h, --help  show this help message and exit

Group title:
  Group description

  --foo FOO   foo help
  --bar BAR   bar help

3.11 버전부터 폐기, 3.14 버전에서 제거: 상호 배제 그룹에서 add_argument_group()이나 add_mutually_exclusive_group()을 호출하면 이제 예외가 발생해요. 이 중첩은 지원된 적이 없고, 종종 올바르게 동작하지 않았으며, 상속을 통해 의도치 않게 노출됐어요.

파서 기본값 (Parser defaults)

ArgumentParser.set_defaults(**kwargs)

대부분의 경우 parse_args()가 반환하는 객체의 속성은 커맨드라인 인자와 인자 action을 검사해 완전히 결정돼요. set_defaults()는 커맨드라인을 전혀 검사하지 않고 결정되는 추가 속성을 추가하게 해 줘요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
>>> parser.set_defaults(bar=42, baz='badger')
>>> parser.parse_args(['736'])
Namespace(bar=42, baz='badger', foo=736)

기본값은 set_defaults()로 파서 수준과 add_argument()로 인자 수준 양쪽에서 설정할 수 있다는 점에 유의하세요. 같은 인자에 대해 둘 다 호출되면 인자에 대해 마지막으로 설정된 기본값이 사용돼요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='bar')
>>> parser.set_defaults(foo='spam')
>>> parser.parse_args([])
Namespace(foo='spam')

파서 수준 기본값은 여러 파서를 다룰 때 특히 유용할 수 있어요. add_subparsers() 메서드에서 이런 유형의 예시를 볼 수 있어요.

ArgumentParser.get_default(dest)

add_argument() 또는 set_defaults()가 설정한 namespace 속성의 기본값을 가져와요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='badger')
>>> parser.get_default('foo')
'badger'

help 출력하기 (Printing help)

대부분의 전형적인 애플리케이션에서 parse_args()가 usage와 오류 메시지를 포맷하고 출력하는 일을 처리해요. 하지만 몇 가지 포맷팅 메서드가 있어요.

ArgumentParser.print_usage(file=None) — 커맨드라인에서 ArgumentParser를 어떻게 호출해야 하는지에 대한 간단한 설명을 출력해요. fileNone이면 sys.stdout으로 가정해요.

ArgumentParser.print_help(file=None) — 프로그램 usage와 ArgumentParser에 등록된 인자에 대한 정보를 포함한 help 메시지를 출력해요. fileNone이면 sys.stdout으로 가정해요.

이 메서드들에는 출력하는 대신 문자열을 반환하는 변형도 있어요.

ArgumentParser.format_usage() — 커맨드라인에서 ArgumentParser를 어떻게 호출해야 하는지에 대한 간단한 설명을 담은 문자열을 반환해요.

ArgumentParser.format_help() — 프로그램 usage와 ArgumentParser에 등록된 인자에 대한 정보를 포함한 help 메시지를 담은 문자열을 반환해요.

부분 파싱 (Partial parsing)

ArgumentParser.parse_known_args(args=None, namespace=None)

때로는 스크립트가 특정 커맨드라인 인자 집합만 처리하고, 인식되지 않는 인자는 다른 스크립트나 프로그램에 남겨둬야 할 때가 있어요. 그런 경우 parse_known_args() 메서드가 유용해요. 이 메서드는 parse_args()와 비슷하게 작동하지만, 추가적이고 인식되지 않는 인자에 대해 오류를 발생시키지 않아요. 대신 알려진 인자를 파싱하고, 채워진 namespace와 인식되지 않은 인자 목록을 포함하는 두 항목 튜플을 반환해요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('bar')
>>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
(Namespace(bar='BAR', foo=True), ['--badger', 'spam'])

경고: 접두사 일치 규칙이 parse_known_args()에도 적용돼요. 파서는 알려진 옵션 중 하나의 접두사일 뿐인 옵션도 남은 인자 목록에 두지 않고 소비할 수 있어요.

파일 파싱 커스터마이징

ArgumentParser.convert_arg_line_to_args(arg_line)

파일에서 읽은 인자(ArgumentParser 생성자의 fromfile_prefix_chars 키워드 인자 참고)는 한 줄에 하나씩 읽혀요. convert_arg_line_to_args()를 재정의해 더 화려한 읽기를 할 수 있어요. 이 메서드는 인자 파일에서 읽은 문자열인 단일 인자 arg_line을 받고, 이 문자열에서 파싱된 인자 리스트를 반환해요. 인자 파일에서 읽은 줄마다 순서대로 한 번씩 호출돼요. 유용한 재정의는 각 공백으로 구분된 단어를 인자로 취급하는 것이에요.

class MyArgumentParser(argparse.ArgumentParser):
    def convert_arg_line_to_args(self, arg_line):
        return arg_line.split()

이 재정의를 쓰면 각 공백으로 구분된 단어가 별도 인자가 되므로, 인자에 더 이상 공백이 포함될 수 없다는 점에 유의하세요.

종료 메서드 (Exiting methods)

ArgumentParser.exit(status=0, message=None)

이 메서드는 프로그램을 종료하고, 지정된 status로 끝나며, 주어진다면 그 전에 sys.stderr에 메시지를 출력해요. 사용자는 이 메서드를 재정의해 이 단계들을 다르게 처리할 수 있어요.

class ErrorCatchingArgumentParser(argparse.ArgumentParser):
    def exit(self, status=0, message=None):
        if status:
            raise Exception(f'Exiting because of an error: {message}')
        exit(status)

ArgumentParser.error(message)

이 메서드는 메시지를 포함한 usage 메시지를 sys.stderr에 출력하고 상태 코드 2로 프로그램을 종료해요.

Intermixed 파싱

ArgumentParser.parse_intermixed_args(args=None, namespace=None) / ArgumentParser.parse_known_intermixed_args(args=None, namespace=None)

많은 Unix 명령은 사용자가 위치 인자와 선택 인자를 섞을 수 있게 해 줘요. parse_intermixed_args()parse_known_intermixed_args() 메서드가 이 파싱 스타일을 지원해요. 이 파서들은 argparse의 모든 기능을 지원하지는 않고, 지원되지 않는 기능이 사용되면 예외를 발생시켜요. 특히 서브파서와 선택 인자·위치 인자를 모두 포함하는 상호 배제 그룹은 지원되지 않아요.

다음 예시는 parse_known_args()parse_intermixed_args()의 차이를 보여줘요. 전자는 ['2', '3']을 파싱되지 않은 인자로 반환하고, 후자는 모든 위치 인자를 rest로 모아요.

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('cmd')
>>> parser.add_argument('rest', nargs='*', type=int)
>>> parser.parse_known_args('doit 1 --foo bar 2 3'.split())
(Namespace(cmd='doit', foo='bar', rest=[1]), ['2', '3'])
>>> parser.parse_intermixed_args('doit 1 --foo bar 2 3'.split())
Namespace(cmd='doit', foo='bar', rest=[1, 2, 3])

parse_known_intermixed_args()는 채워진 namespace와 남은 인자 문자열 목록을 포함하는 두 항목 튜플을 반환해요. parse_intermixed_args()는 파싱되지 않은 인자 문자열이 남아 있으면 오류를 발생시켜요.

3.7 버전에서 추가.

커스텀 타입·action 등록

ArgumentParser.register(registry_name, value, object)

때로는 오류 메시지에서 커스텀 문자열을 사용해 더 사용자 친화적인 출력을 제공하는 게 바람직할 수 있어요. 그런 경우 register()로 커스텀 action이나 타입을 파서에 등록하고, callable 이름 대신 등록된 이름으로 타입을 참조하게 할 수 있어요. register() 메서드는 세 인자를 받아요 — 객체가 저장될 내부 레지스트리를 지정하는 registry_name(예: action, type), 객체가 등록될 키인 value, 그리고 등록할 callable인 object예요.

다음 예시는 파서에 커스텀 타입을 등록하는 방법을 보여줘요.

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.register('type', 'hexadecimal integer', lambda s: int(s, 16))
>>> parser.add_argument('--foo', type='hexadecimal integer')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type='hexadecimal integer', choices=None, required=False, help=None, metavar=None, deprecated=False)
>>> parser.parse_args(['--foo', '0xFA'])
Namespace(foo=250)
>>> parser.parse_args(['--foo', '1.2'])
usage: PROG [-h] [--foo FOO]
PROG: error: argument --foo: invalid 'hexadecimal integer' value: '1.2'

예외 (Exceptions)

exception argparse.ArgumentError

인자(선택 또는 위치)를 만들거나 사용할 때의 오류예요. 이 예외의 문자열 값은 그 오류를 일으킨 인자에 대한 정보가 보강된 메시지예요.

exception argparse.ArgumentTypeError

커맨드라인 문자열을 타입으로 변환할 때 문제가 생기면 발생해요.

더 알아보기

  • Argparse Tutorial — argparse 사용법 튜토리얼
  • Migrating optparse code to argparse — optparse 코드를 argparse로 옮기는 가이드