2012-08-28 5 views
5

argparse.ArgumentParser 개체의 전역 옵션을 사용하여 하위 명령의 기본값을 재정의/추가 할 수 있기를 원합니다.전역 옵션을 통해 argparse augment 하위 명령이 기본값으로 설정됩니다.

예 것이라고 표시 도움이 다음과 같은 장난감 예를 들어 글로벌 업데이트, 즉, 반영 될 : I 도움이 모드에서이 프로그램을 실행할 때 내가 얻을 것이 이상적

import argparse 
import os 
import sys 

# Global parser and options. 
parser = argparse.ArgumentParser(
    formatter_class=argparse.ArgumentDefaultsHelpFormatter) 

parser.add_argument("--user", 
        dest="user", 
        default=os.environ.get("USER"), 
        help="Override the setting of the $USER variable.") 

# Sub-command parser and options. 
subparsers = parser.add_subparsers() 

command = subparsers.add_parser(
    "command", 
    formatter_class=argparse.ArgumentDefaultsHelpFormatter) 

command.add_argument("--config", 
        dest="config", 
        default="~%s/config" % os.environ.get("USER"), 
        help="The config file.") 

options = parser.parse_args() 

> python example.py --user thing command --help 
usage: example.py command [-h] [--config CONFIG] 

optional arguments: 
    -h, --help  show this help message and exit 
    --config CONFIG The config file. (default: ~thing/config) 

즉, 설정 파일 경로는 사용자 고유 (thing)입니다. 나는 기본 설정을 "~%(user)s/config"으로 변경 한 다음 옵션 네임 스페이스를 사용하여 런타임에이 문제를 해결할 수 있음을 알고 있습니다.하지만 좀 더 명확하게 설명하고 싶습니다. 이 다소 해키 보이지만

나는

if "--help" in sys.argv: 

    # Parse the command minus the help to obtain the global options. 
    args = sys.argv[1:] 
    args.remove("--help") 

    # Update the defaults with the global options. 
    options = parser.parse_args(args) 
    command.set_defaults(config="~%s/config" % options.user) 

    # Re-parse the options. 
    parser.parse_args() 

, 대체 솔루션이 글로벌 옵션을 얻기 위해 한 번 인수를 구문 분석, 즉하려고하는 것입니다 수집합니다. 더 나은 접근법/해결책이 있습니까?

답변

4

전역 옵션을 정의한 후 하위 명령을 정의하기 전에 parse_known_args을 호출하여 --user의 값이 무엇인지 확인하십시오. 그런 다음 --user의 값을 사용하여 의 기본값을 정의한 다음, 을 호출하여 명령 줄의 모든 옵션을 구문 분석하여 하위 매개 변수 명령을 정의합니다.

이 방법은 대안과 약간 다르지만 모든 명령 줄 처리를 argparse 개체 안에 유지합니다.

import os 
import argparse 

# Global preparser and options. 
preparser = argparse.ArgumentParser(add_help=False) 
preparser.add_argument("--user", dest="user", default=os.environ.get("USER")) 

# ****** NEW ******* 
options, _ = preparser.parse_known_args() # Ignore what we haven't defined yet 
user = options.user      # Use this to define the default of --config 

parser = argparse.ArgumentParser(parents=[ preparser ], add_help=True, 
        formatter_class=argparse.ArgumentDefaultsHelpFormatter) 

# Sub-command parser and options. 
subparsers = parser.add_subparsers() 

command = subparsers.add_parser("command") 

# ****** MODIFIED ******* 
command.add_argument("--config", dest="config", default="~%s/config" % (user,)) 

options = parser.parse_args() 
+0

감사를 사용자 정의됩니다. 이 접근법은 제 접근법보다 훨씬 깔끔하고 단순하며 argparse없이 시도한 접근법, 즉 인수를 두 번 파싱하는 것과 유사합니다. 필자는 예제에 따라 "--help"인수를 제공하지 않고 parse_known_args()를 사용하여 옵션을 반환하는 방법 (exit와 반대)을 얻을 수있는 코드를 살펴볼 수 있습니다. – John

+0

오, 잊어 버렸습니다. 'parse_known_args()'가'ArgumentParser.exit' ('sys.exit'를 둘러싸고 비교적 얇은 래퍼)를 호출 할 때 throw하는'SystemExit' 예외를 잡을 수 있습니다. – chepner

+0

이봐, 그래, 그 시도했지만 try/except 문제는 ​​옵션이 정의되지 않은 것입니다. – John

0

여기 런타임에 직접 도움 라인을 수정하는 솔루션입니다 (난 당신의 코드를 약간 그냥 대답을 단축 할 수 있습니다. 아래 정돈). 그것은 또한 os.environ 또는 다른 글로벌을 수정할 수도 있지만 간단하게 유지할 것입니다. 열쇠는 add_argument('--config'...)에 의해 생성 된 동작을 변수에 할당하는 것입니다. help은 해당 변수의 속성 일뿐입니다. 당신은 그것을 자유롭게 수정할 수 있습니다. 단지 cmd -h로 호출

class FooAction(argparse.Action): 
    def __call__(self, parser, namespace, values, option_string=None): 
     config.help = 'new user (%s)'% values 
     setattr(namespace, self.dest, values) 

parser = argparse.ArgumentParser() 
parser.add_argument('--user',action=FooAction) 
sub = parser.add_subparsers() 
cmd = sub.add_parser('cmd') 
config = cmd.add_argument('--config',help='initial help') 
config.help = 'default help' # alt way of setting 'help' 
# print config # to see other attributes of the config action 
args = parser.parse_args() 
print args 

우리가 --user xxx cmd -h로 불려 default help

$ python stack12167228.py cmd -h 
usage: stack12167228.py cmd [-h] [--config CONFIG] 

optional arguments: 
    -h, --help  show this help message and exit 
    --config CONFIG default help 

를 얻을 도움이 응답

$ python stack12167228.py --user xxx cmd -h 
usage: stack12167228.py cmd [-h] [--config CONFIG] 

optional arguments: 
    -h, --help  show this help message and exit 
    --config CONFIG new user (xxx)