2017-10-26 8 views
0

I script.py에 다음 코드가 있습니다argparse에서 기본 서브 파서를 선택하는 방법은 무엇입니까?

$ python3 script.py 
Namespace(command='a') 
$ python3 script.py a 
Namespace(command='a', thing='thing') 
$ python3 script.py b 
Namespace(command='b', nothing='nothing') 

이와 단 하나의 문제가있다 :

import argparse 

parser = argparse.ArgumentParser() 
sp = parser.add_subparsers(dest='command') 
sp.default = 'a' 

a_parser = sp.add_parser('a') 
b_parser = sp.add_parser('b') 

a_parser.add_argument('--thing', default='thing') 
b_parser.add_argument('--nothing', default='nothing') 

args = parser.parse_args() 
print(args) 

나는이 세 가지 방법으로 호출 할 수 있습니다 제가을 원하는 것은 그런 내가 제로를 제공하는 경우 커맨드 라인에서의 인수는 a_parser이 파싱을 끝내고 물건을 만드는 것입니다. 분명히 아니에요. sp.default은 단지 command='a'으로 설정되어 있습니다. "오 그래, 사용자가 명령 줄에서 아무런 인수도 제공하지 않았지만,이 값을 a_parser으로 처리해야한다는 것을 알고 있습니다. Namespace(command='a', thing='thing')! "

나는 수 있습니까? argparse 함께 할거야? 몇 가지 옵션을 찾았지만, 그 중 어느 것도 실제로 내가 제공 한 것을 제공하지 않는 것 같습니다. 나는 3 개의 다른 ArgumentParser를 만들고 각각에 인수를 전달하면서 약간의 위 j을 할 수 있다고 생각하지만, 약간의 총합이 들린다.

더 나은 옵션이 있습니까?

+0

당신은 같은 명령 줄 프레임 워크를 조사 할 수 [절벽] (https://pypi.python.org/pypi/cliff) 또는 [클릭]를 이런 종류의 디자인 지원. – larsks

+0

더 나은 사용 docopt – Nickpick

답변

2

처음에는 역사적인 노트 - 서브 파서는 선택 사항이 아니며 여전히 파이썬 2에 포함되어 있지 않습니다. Py3에서 선택 사항이라는 사실은 몇 년 전에 소개 된 버그입니다. 테스트에서 요구되는 주장에 대한 변화가 있었고, 서브 펄서 (일종의 위치)가 균열을 빠져 나갔습니다. 올바르게 수행 되었다면 명시 적으로 subparser를 필수가 아닌 것으로 설정해야했습니다.

서브 파서는 nargs='?'이거나 required 매개 변수없이 플래그가 지정된 다른 필수 인수와 같이 동작하지 않습니다.

어떤 경우에도 sp.defaultcommand 대상에 넣을 값을 정의하지만 a_parser은 사용하지 않습니다. 그 command='a' 결코 '평가'.

parse_known_args을 사용하면 a_parser으로 나머지 문자열을 평가 절하 할 수 있습니다. 인수없이

, 우리는 할 수 있습니다

In [159]: args, extras = parser.parse_known_args([]) 
In [160]: args 
Out[160]: Namespace(command='a') 
In [161]: extras 
Out[161]: [] 

을 다음 조건

In [163]: a_parser.parse_args(extras,namespace=args) 
Out[163]: Namespace(command='a', thing='thing') 

(명령 '은'하지만 '일'인 경우) a_parser을 실행하지만이 포함하려고하면 --thing 값 : 그것은 subparser로 '아야'를 구문 분석을 시도

In [164]: args, extras = parser.parse_known_args('--thing ouch'.split()) 
usage: ipython3 [-h] {a,b} ... 
ipython3: error: argument command: invalid choice: 'ouch' (choose from 'a', 'b') 

이름. 주 파서는 --thing 인수에 대해 아무것도 모릅니다.

오늘 다른 argparse 질문에서 설명한 것처럼 최상위 파서는 'subparsers'명령에 맞는 (또는이 예에서는 오류 발생) 입력을 파싱합니다. 그런 다음 파싱을 하위 파서로 전달합니다. 이후 파싱을 재개하지 않습니다.

Add top level argparse arguments after subparser args

How to Set a Default Subparser using Argparse Module with Python 2.7

이 Py2 요청에 대한 내 대답

당신을 위해 작동 할 수 있습니다. 먼저 서브 컴파일러가없는 파서를 사용하여 parse_known_args을 실행하고 조건에 따라 서브 파서를 처리하는 두 번째 파서를 실행합니다. extras 만약

In [165]: firstp = argparse.ArgumentParser() 
In [166]: args, extras = firstp.parse_known_args('--thing ouch'.split()) 
In [167]: args 
Out[167]: Namespace() 

는 'A'또는 'B'(바로 직접 sys.argv[1:] 볼 택일) a_parser 전화를 가지고 있지 않습니다

In [168]: extras 
Out[168]: ['--thing', 'ouch'] 
In [169]: a_parser.parse_args(extras) 
Out[169]: Namespace(thing='ouch') 

또는 누락 subparser 명령을 포함하는 extras을 수정

In [170]: extras = ['a']+extras 
In [171]: parser.parse_args(extras) 
Out[171]: Namespace(command='a', thing='ouch') 

어쨌든 optional subparser는 argparse에 잘 발달되지 않았습니다. 그것은 잘 생각한 기능이 아니라 변화가 가져온 부작용입니다. 일반적으로 더 나은 제공하는 (http://click.pocoo.org/5/)