2012-11-12 3 views
11

위치 지정 인수를 가질 수 있는지 여부는 선택적 인수와 함께 인수 뒤에옵니다. 이상적으로 명령 행에 입력 된 마지막 인수는 항상 'testname'에 적용됩니다.argparse 위치 지정 인수 앞에 선택적 인수가 있습니다.

import argparse 
parser = argparse.ArgumentParser(description='TAF') 
parser.add_argument('-r','--release',nargs='?',dest='release',default='trunk') 
parser.add_argument('testname',nargs='+') 
args = parser.parse_args() 

두 호출 모두 testname에 smoketest를 적용하고 싶지만 두 번째 호출은 오류가 발생합니다.

>> python TAF.py -r 1.0 smoketest 
>> python TAF.py -r smoketest 
TAF.py: error: too few arguments 

내가 전면에 위치 인수를 이동하는 선택적 매개 변수의 올바른 동작이 발생할 것이라고 실현, 그러나 이것은 내가 찾고 있어요 아주 형식이 아닙니다. 선택 플래그는 매력적인 대안처럼 보이지만 일치하지 않는 항목을 무시하는 대신 오류가 발생합니다.

편집 : 나는 이것에 대해 해커를 발견했습니다. 누군가가 더 좋은 해결책을 가지고 있다면 나는 그것을 고맙게 생각할 것이다. documentation에 명시된 바와 같이

import argparse 
parser = argparse.ArgumentParser(description='TAF') 
parser.add_argument('-r','--release',nargs='?',dest='release',default='trunk') 
parser.add_argument('testname',nargs=argparse.REMAINDER) 
args = parser.parse_args() 

if not args.testname: 
    args.testname = args.release 
    args.release = '' 

답변

3

:

'?'. 가능하면 명령 행에서 하나의 인수가 사용되며 이며 단일 항목으로 생성됩니다. 명령 줄 인수가 없으면 기본값에서 값이 생성됩니다. 옵션 인 인수의 경우 추가 옵션이 있습니다. 옵션 문자열은 이지만 명령 행 인수는 뒤에 없습니다. 이 경우 const에서 값 이 생성됩니다.

따라서 원하는 동작은 '?'을 사용하여 얻을 수 없습니다. 아마도 argparse.Action을 사용하여 해킹을 작성하고 이전 결과와 간섭 할 수 있습니다. (1)

더 좋은 해결책은 해당 옵션의 기능을 분할하는 것입니다. 인수가 필요한 옵션으로 설정하고 (옵션 자체는 선택 사항 임) 릴리스없이 'trunk'으로 설정하는 인수없이 옵션을 추가하십시오. 이 방법으로 해킹없이 동일한 결과를 얻을 수 있습니다. 또한 인터페이스가 더 간단하다고 생각합니다. 당신의 예에서

:

python TAF.py -r smoketest 

그것은 smoketest-r에 인수로 해석 될 것이라는 점을 매우 분명하다. 적어도 유닉스 컨벤션 이후. 당신은 사용자 해야에게 다음 사용 --nargs='?'을 유지하려면 :

$ python TAF.py -r -- sometest 
Namespace(release=None, testname=['sometest']) #parsed result 

(1)이 작업을 수행하는 방법에 대한 아이디어는 : 옵션 인수가 있는지 확인합니다. 유효한 테스트 이름인지 한 번 확인하십시오. 그렇다면 testname에 손으로 넣고 release을 기본값으로 설정하십시오. 당신은 또한이 일이 일어났다 고 알려주는 "깃발 (flag)"을 설정해야합니다.

이제 sys.argv을 구문 분석하기 전에 sys.stderr을 리디렉션해야합니다.구문 분석을 수행 할 때 SystemExit을 잡아야하며 stderr을 확인하고 "너무 적은 인수"인지 확인하고 플래그가 설정되었는지 확인한 다음 오류를 무시하고 계속 실행하십시오. 그렇지 않으면 원래 stderr 오류로 다시 인쇄해야합니다 메시지와 종료.

이 접근법은 강력하지 않으며 버그가있을 수 있습니다.

+0

응답 해 주셔서 감사합니다. 필자는 testname 인수에 대한 접두어를 추가하거나 두 번째 인수 앞에 나열한 것에 대해서도 언급했듯이 깔끔하게 마무리 할 수 ​​있다는 것에 동의합니다. –