파이썬 argparse를 접두사없이 상호 배타적 인 그룹 인수로 만드는 방법은 무엇입니까?


79

Python2.7 argparse는 상호 배타적 인 그룹에서 선택적 인수 (접두사) 만 허용합니다.

parser = argparse.ArgumentParser(prog='mydaemon')
action = parser.add_mutually_exclusive_group(required=True)
action.add_argument('--start', action='store_true', help='Starts %(prog)s daemon')
action.add_argument('--stop', action='store_true', help='Stops %(prog)s daemon')
action.add_argument('--restart', action='store_true', help='Restarts %(prog)s daemon')

$ mydaemon -h

usage: mydaemon [-h] (--start | --stop | --restart)

optional arguments:
  -h, --help  show this help message and exit
  --start     Starts mydaemon daemon
  --stop      Stops mydaemon daemon
  --restart   Restarts mydaemon daemon

argparse 인수가 기존의 유닉스 데몬 제어처럼 작동하도록 만드는 방법이 있습니까?

(start | stop | restart) and not (--start | --stop | --restart) ?

답변:


75

모든 능력과 옵션에 argparse대해 당신이 원하는 것처럼 보이는 "미리 준비된"사용 문자열을 얻을 수 없을 것이라고 생각합니다.

즉, 원래 게시물 이후 하위 파서를 살펴 보셨습니까?

다음은 베어 본 구현입니다.

import argparse

parser = argparse.ArgumentParser(prog='mydaemon')
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon')
sp_stop = sp.add_parser('stop', help='Stops %(prog)s daemon')
sp_restart = sp.add_parser('restart', help='Restarts %(prog)s daemon')

parser.parse_args()

-h옵션을 사용하여 실행하면 다음이 생성됩니다.

usage: mydaemon [-h] {start,stop,restart} ...

positional arguments:
  {start,stop,restart}
    start               Starts mydaemon daemon
    stop                Stops mydaemon daemon
    restart             Restarts mydaemon daemon

이 접근 방식의 이점 중 하나는 set_defaults각 하위 구문 분석기를 사용 하여 함수를 인수에 직접 연결할 수 있다는 것입니다. stop및에 대한 "우아한"옵션도 추가했습니다 restart.

import argparse

def my_stop(args):
    if args.gracefully:
        print "Let's try to stop..."
    else:
        print 'Stop, now!'

parser = argparse.ArgumentParser(prog='mydaemon')

graceful = argparse.ArgumentParser(add_help=False)
graceful.add_argument('-g', '--gracefully', action='store_true', help='tries to terminate the process gracefully')
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon')
sp_stop = sp.add_parser('stop', parents=[graceful],
                    description='Stops the daemon if it is currently running.',
                    help='Stops %(prog)s daemon')
sp_restart = sp.add_parser('restart', parents=[graceful], help='Restarts %(prog)s daemon')

# Hook subparsers up to functions
sp_stop.set_defaults(func=my_stop)

# Uncomment when my_start() and 
# my_restart() are implemented
#
# sp_start.set_defaults(func=my_start)
# sp_restart.set_defaults(func=my_restart)

args = parser.parse_args()
args.func(args)

에 대한 "도움말"메시지 표시 stop:

$ python mydaemon.py stop -h
usage: mydaemon stop [-h] [-g]

Stops the daemon if it is currently running.

optional arguments:
  -h, --help        show this help message and exit
  -g, --gracefully  tries to terminate the process gracefully

"정상적으로"중지 :

$ python mydaemon.py stop -g
Let's try to stop...

그러나 어떤 시작 중지 또는 다시 시작 옵션이 선택되었는지 확인하는 방법은 표시하지 않습니다. 인수의 재현을 보려고 할 때 하위 파서 인수가 표시되지 않습니다.
Ronaldo Nascimento

@RonaldoNascimento 여기에 귀하의 질문에 대한 답변이 있다고 생각합니다. docs.python.org/3/library/… 조금 아래로 스크롤하면이 문제를 해결하는 방법에 대한 예가 있습니다set_defaults
OriolAbril

@RonaldoNascimento 늦었지만 내 편집이 귀하의 질문에 대답한다고 생각합니다. my_stop ()에 대한 set_defaults ()는 항상 거기에 있었지만 쉽게 간과되었습니다. 귀하의 질문에 대한 단서를 얻기 위해 호날두의 의견이 필요했습니다. 그리고 나는 당신이 기대했던 것을 보여주지 않은 repr ()로 무엇을하는지 잘 모르겠습니다.
Zach Young

79

에서 pymotw

import argparse

parser = argparse.ArgumentParser()

group = parser.add_mutually_exclusive_group()
group.add_argument('-a', action='store_true')
group.add_argument('-b', action='store_true')

print parser.parse_args()

산출:

$ python argparse_mutually_exclusive.py -h  
usage: argparse_mutually_exclusive.py [-h] [-a | -b]

optional arguments:  
  -h, --help  show this help message and exit  
  -a  
  -b  

$ python argparse_mutually_exclusive.py -a  
Namespace(a=True, b=False)

$ python argparse_mutually_exclusive.py -b  
Namespace(a=False, b=True)

$ python argparse_mutually_exclusive.py -a -b  
usage: argparse_mutually_exclusive.py [-h] [-a | -b]  
argparse_mutually_exclusive.py: error: argument -b: not allowed with argument -a

버전 2

import argparse

parser = argparse.ArgumentParser()

subparsers = parser.add_subparsers(help='commands')

# A list command
list_parser = subparsers.add_parser('list', help='List contents')
list_parser.add_argument('dirname', action='store', help='Directory to list')

# A create command
create_parser = subparsers.add_parser('create', help='Create a directory')
create_parser.add_argument('dirname', action='store', help='New directory to create')
create_parser.add_argument('--read-only', default=False, action='store_true',
                       help='Set permissions to prevent writing to the directory',
                       )

# A delete command
delete_parser = subparsers.add_parser('delete', help='Remove a directory')
delete_parser.add_argument('dirname', action='store', help='The directory to remove')
delete_parser.add_argument('--recursive', '-r', default=False, action='store_true',
                       help='Remove the contents of the directory, too',
                       )

print parser.parse_args(['list', 'a s d', ])
>>> Namespace(dirname='a s d')
print parser.parse_args(['list', 'a s d', 'create' ])
>>> error: unrecognized arguments: create

39

상호 배타적 인 옵션 대신 위치 인수를 원하는 것처럼 들립니다. '선택'을 사용하여 가능한 허용 옵션을 제한 할 수 있습니다.

parser = ArgumentParser()
parser.add_argument('action', choices=('start', 'stop', 'restart'))

이렇게하면 다음과 같은 사용 라인이 생성됩니다.

usage: foo.py [-h] {start,stop,restart}

그래, 나는 그것을 보았지만 선택은 사용의 표현을 제한합니다. 접두사를 제거하는 방법을 찾고 있습니다.
Carlo Pires

"사용의 표현력 제한"이란 무엇을 의미합니까? 사용자가 이들 중 하나를 제공하지 않고 스크립트를 실행할 수 있습니까?
Adam Wagner

사용자가 "mydaemon -h"를 실행하면 도움말 (사용법)이 각 인수에 대한 도움말 문자열을 사용하는 것처럼 명확하지 않습니다.
Carlo Pires 2011 년

1
@AdamWagner 사용자가 둘 이상의 인수를 전달하면 어떻게됩니까? 예foo.py start stop
Santosh Kumar

귀하의 예에서 @SantoshKumar, 'stop'은 첫 번째 위치 인수가 아니므로 위의 예제에서 하나의 인수 만 정의되면 'stop'을 인식하지 않는다는 오류가 발생합니다 (예시에서). 두 번째 위치 인수를 정의한 경우 'start'는 첫 번째 값이되고 'stop'은 두 번째 값이됩니다.
Adam Wagner

13

Adam의 대답을 기반으로 ... 기본값을 지정하려면 항상 다음을 수행하여 효과적으로 공백으로 둘 수 있습니다.

import argparse

ActionHelp = """
    Start = Starts the daemon (default)
    Stop = Stops the daemon
    Restart = Restarts the daemon
    """
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)

parser.add_argument('action', nargs = '?', choices=('start', 'stop', 'restart'),
    default = 'start', help = ActionHelp)

print parser.parse_args(''.split())
print
print parser.parse_args('-h'.split())

다음과 같이 인쇄됩니다.

Namespace(action='start')

usage: program.py [-h] [{start,stop,restart}]

postional arguments:
    {start,stop,restart}
                      Start = Starts the daemon (default)
                      Stop = Stops the daemon
                      Restart = Restarts the daemon

optional arguments:
    -h, --help        show this help message and exit
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.