2012-12-09 5 views
4

나는 다음과 같은 서명 인수 파서를 만들려면 : 그는 인수 -a를 제공하는 경우파이썬 ArgumentParser 중첩 인수

./myapp [-a [-b BVAL] | -c]

즉, 사용자는 경우에 인수 -b BVAL을 제공 할 수있다.

그것은 -a-c의 상호 배타적 인 그룹을 생성하는 것은 매우 쉽지만, (나는 그것은 당신이 찾고있는 아니에요 정확히 allow -b only if -a provided

답변

4

Docopt은 내가 원하는대로 그것을 않습니다. 훌륭한!

docopt('./myapp [-a [-b BVAL] | -c]') 
+1

표준 라이브러리에 있어야합니다! 얼마나 많은 질문을 보았습니까? 누군가가 원하는 사용 문서를 게시 한 다음 argparse를 사용하여 원하는 용도의 문서를 작성할 수 없습니다. 그것은 단지 거꾸로 잘못되었습니다. 사용 설명서를 해석하는 방법을 알고 있습니다. 왜 우리 코드를 사용할 수 없습니까? Docopt 않습니다. –

2

관계를 만드는 방법을 알아낼 수 없습니다하지만 어쩌면 당신이 add_subparsers()를 사용할 수 있는지 doc)?

같은 것을 수행

import argparse 
parser = argparse.ArgumentParser() 
subparsers = parser.add_subparsers(help='sub-command help') 
a = subparsers.add_parser('a') 
c = subparsers.add_parser('c') 
a.add_argument('b') 
+0

예, 그렇습니다. 누군가가 내가 찾고있는 것에 더 가까운 해결책을 제시 할 수있을 때까지 기다리 자. 더 좋은 대답이 없다면, 나는 서브 파서와 함께 갈거야, 고마워. – kovpas

+1

Subparsers는 이전에이 용도로 사용했던 것입니다. –

2

당신이 subparsers를 사용하지 않으려면, 당신이 당신의 인수가 parser.error를 사용하여 자신의 가치를 처리 할 수 ​​있습니다.

import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument('-a', dest='a', default='') # you can use other defaults surely 
parser.add_argument('-b', dest='b', default='') 
parser.add_argument('-c', dest='c', default='') 

args = parser.parse_args() 

if args.b and not args.a: 
    parser.error("Option 'b' can't be specified without 'a'") 

하지만 여전히 당신은 일부 사용자 지정 기능을 추가하는 당신은 ArgumentParser에서 상속 할 수있는 논리

5

을 확장 할 수있는 경우에 subparsers을 사용하는 것이 좋습니다. 여기에 예외가 발생하지만, 이것을 수정하여 원하는 것을 구현할 수 있습니다. 필요에 맞게 on_dependency_error() 메서드를 변경하면됩니다.

from argparse import ArgumentParser 

class FancyParser(ArgumentParser): 
    # {'b': 'a'} Where b depends on a 
    dependencies = {} 

    def on_dependency_error(self, arg, depends_on): 
     raise FancyParser.DependencyError(
        'Argument %s depends on %s' % (arg, depends_on)) 

    def add_argument(self, *args, **kwargs): 
     depends_on = kwargs.get('depends_on') 
     if depends_on: 
      self.dependencies[kwargs.get('dest') or args[0]] = depends_on 
      del kwargs['depends_on'] 
     return super(FancyParser, self).add_argument(*args, **kwargs) 

    def parse_args(self, *args, **kwargs): 
     args = super(FancyParser, self).parse_args(*args, **kwargs) 
     for arg, depends_on in self.dependencies.iteritems(): 
      if getattr(args, arg) and not getattr(args, depends_on): 
       self.on_dependency_error(arg, depends_on) 
     return args 

    class DependencyError(Exception): 
     def __init__(self, *args, **kwargs): 
      return super(FancyParser.DependencyError, 
         self).__init__(*args, **kwargs) 

당신은 다음과 같이 사용할 수 있습니다 -

args = ['-a', '-b', 'BVAL', '-c'] 
parser = FancyParser() 
parser.add_argument('-a', dest='a', action='store_true') 
parser.add_argument('-b', dest='b', depends_on='a') 
parser.add_argument('-c', dest='c', action='store_true') 
try: 
    parser.parse_args(args) 
except FancyParser.DependencyError as e: 
    # Whatever here... 
    pass 
+0

굉장! 시도해 볼게요, 고마워요. – kovpas

+1

문제가 없습니다! 의존성을 테스트하기 위해'parse_args()'메소드를 업데이트했습니다. 업데이트 된 코드를 사용하는 것이 좋습니다. 감사! – pyrospade