2013-09-04 3 views
7

확실한 것을 놓치고 있어야합니다. 목표는 첫 번째 필수 매개 변수, 두 번째 선택적 매개 변수 및 기타 나머지 매개 변수를 선택적으로 사용하여 argparse를 사용하는 것입니다.Python argparse : 선택적 매개 변수를 nargs = argparse.REMAINDER와 결합하십시오.

문제를 표시하기 위해 두 개의 테스트 파서를 만들었습니다. 그들 사이의 유일한 차이점은 nargs = argparse.REMAINDER를 하나, nargs = '*'를 다른 것에 사용하는 것입니다.

def doParser1(argsin): 
    parser = argparse.ArgumentParser(description='Parser demo.') 
    parser.add_argument('req1', help='first required parameter') 
    parser.add_argument('--opt1', help='first optional parameter') 
    parser.add_argument('leftovers', nargs=argparse.REMAINDER, 
        help='all the other parameters') 
    argsout = parser.parse_args(args=argsin) 
    print argsout 
    return argsout 

def doParser2(argsin): 
    parser = argparse.ArgumentParser(description='Parser demo.') 
    parser.add_argument('req1', help='first required parameter') 
    parser.add_argument('--opt1', help='first optional parameter') 
    parser.add_argument('leftovers', nargs='*', 
        help='all the other parameters') 
    argsout = parser.parse_args(args=argsin) 
    print argsout 
    return argsout 

추가 매개 변수가없는 경우 parser2가 작동합니다. 이 parser1 파서 한 다음에 입력된다 : 추가 파라미터가 있으면

input: ['req1value', '--opt1', 'opt1value'] 
Namespace(leftovers=['--opt1', 'opt1value'], opt1=None, req1='req1value') 
Namespace(leftovers=None, opt1='opt1value', req1='req1value') 

상기 OPT1 값 parser1에서 누락되고 parser2는 혼동 얻는다 :

input: ['req1value', '--opt1', 'opt1value', 'r1', 'r2'] 
Namespace(leftovers=['--opt1', 'opt1value', 'r1', 'r2'], opt1=None, req1='req1value') 
usage: py-argparse.py [-h] [--opt1 OPT1] 
        [-leftovers [LEFTOVERS [LEFTOVERS ...]]] 
        req1 
py-argparse.py: error: unrecognized arguments: r1 r2 

예상 출력 같아야

Namespace(leftovers=['r1', 'r2'], opt1='opt1value', req1='req1value') 

이것은 간단한 사례 여야하며 여기에있는 내용이 실제로 수행하려고 시도하는 것으로부터 단순화 된 것 같습니다. 남은 부분을 선택 사항으로 만들려고 시도했지만 다른 옵션은 다양하지만 더 좋은 것은 없습니다.

도움을 주시면 감사하겠습니다.

답변

3

--opt1은 "이름이없는"인수 앞에 와야합니다. 실제 테스트 케이스가 있어야한다 :

['--opt1', 'opt1value', 'req1value'] 

['--opt1', 'opt1value', 'req1value', 'r1', 'r2'] 
+0

나는 그것이 단순해야한다는 것을 알고있었습니다. 나는 어디에서나 문서에서 그것을 보지 못했지만, nargs = argparse.REMAINDER에서 작동합니다. 그리고 그게 전부입니다. 감사. – OPunWide

4

당신은 parse_known_args을 사용할 수

import argparse 
parser = argparse.ArgumentParser(description='Parser demo.') 
parser.add_argument('req1', help='first required parameter') 
parser.add_argument('--opt1', help='first optional parameter') 

args, leftovers = parser.parse_known_args(['req1value', '--opt1', 'opt1value']) 
print(args, leftovers) 
# (Namespace(opt1='opt1value', req1='req1value'), []) 

args, leftovers = parser.parse_known_args(['req1value', '--opt1', 'opt1value', 'r1', 'r2']) 
print(args, leftovers) 
# (Namespace(opt1='opt1value', req1='req1value'), ['r1', 'r2']) 
+0

나중에이 파일을 보내 드리겠습니다. 다른 대답은 내가 원하는 것에 적합했다. 이 솔루션은 첫 번째 옵션이 필요하지 않은 것 같습니다. 맞습니까? – OPunWide

+0

오른쪽. 이것은 인수를 어떤 순서로든 수용합니다. 일치하지 않는 사람은 '남은 음식'으로 끝납니다. – unutbu

+0

좋은 해결책. 그러나 이전 * remainder *는 더 이상 documentation/help에 표시되지 않습니다. – hitzg

2

positionals 및 선택적 항목의 상호 혼합이 어려운 경우 하나 또는 positionals의 더 '0 개 이상'유형 (? * REMAINDER)입니다. 간단한 해결책은 그 (것)들을 섞지 않기위한 것이다 - 선택권을 첫째로, 그 후에 모든 위치를 준다.

여기에 무슨 일이 일어나고 있는지의 :

input: ['req1value', '--opt1', 'opt1value'] 
Namespace(leftovers=['--opt1', 'opt1value'], opt1=None, req1='req1value') 

을 때문에 파서가 처음 positionals에 대한 구문 분석 req1value 문자열. req1leftovers 그랩 그 밖의 모든 것을 --opt1을 포함하여 1 개의 문자열을 원합니다. *leftovers

Namespace(leftovers=None, opt1='opt1value', req1='req1value') 

그러므로 None (실제로 내가 []를 얻을), [], 아니 문자열을 만족한다. --opt1은 선택적으로 구문 분석됩니다.

input: ['req1value', '--opt1', 'opt1value', 'r1', 'r2'] 
... 
py-argparse.py: error: unrecognized arguments: r1 r2 

으로 이전 *leftovers[]로 설정됩니다. -opt1이 처리됩니다. 그러나 지금은 그들을 놓을 곳이없는 2 개의 현이 있습니다. 당신은 그들이 leftovers에 들어가기를 의도 했었지만 이미 사용되었습니다. leftovers+ 인 경우 의도 한대로 촬영했을 것입니다.

키는 첫 번째 위치를 구문 분석하려고 할 때 가능한 모든 위치를 구문 분석하려고합니다. 한 수준에서 parse_args('A', '') 그룹을 생산하는 re.match('(A)(A*)','AOA')입니다.

이 문제를 해결할 수있는 두 가지 제안 된 패치가 있습니다. 하나는 2 단계 parse_known_args을 사용하여 선택 사항과 위치 지정을 완전히 혼합 할 수 있습니다. 이것은 optparse의 사용자가 기대할 수있는 행동 유형입니다.

다른 패치는 0 인수 문자열 http://bugs.python.org/issue15112을 허용 할 수있는 위치 지정 처리를 지연 시키려고 시도합니다.

관련 문제