5

Here is my code portion:

parser = argparse.ArgumentParser()
parser.add_argument('-a', action='store', dest='xxx', default = 'ABC')
parser.add_argument('-b', action='store', dest='yyy')
parser.add_argument('-c', action='store', dest='zzz')
args = parser.parse_args()

I want the code to work like this:

If b and c are given, do command2. Otherwise, do command1

if -a argument is given, then adding -b or -c throws an error

I tried this way:

if args.xxx and (args.yyy or args.zzz):
   parser.print_help()
   sys.exit()

But it didn't worked, because '-a' always has a deafult value and i can't change it. How can i fix it?

7
  • 1
    remove the default value for a Commented Jul 30, 2014 at 11:01
  • I need the default value :( Commented Jul 30, 2014 at 11:02
  • If -a is the set as the default do you want -b and -c? Commented Jul 30, 2014 at 11:08
  • No, it doesen't matter. I want to make a switch. If a is given(or not), then do command1 if b and c is given, then do command2 Commented Jul 30, 2014 at 11:12
  • 1
    You can use a mutually exclusive group for a or b and c. docs.python.org/2/howto/argparse.html#conflicting-options But not sure how you would declare b and c not exclusive. Commented Jul 30, 2014 at 11:12

2 Answers 2

3

Here's one way to do it:

# If option xxx is not the default, yyy and zzz should not be present.
if args.xxx != 'ABC' and (args.yyy or args.zzz):
   # Print help, exit.

# Options yyy and zzz should both be either present or None.
if (args.yyy is None) != (args.zzz is None):
   # Print help, exit.

# Earn our pay.
if args.yyy is None:
    command2()
else:
    command1()

You might also consider a usage pattern based on subcommands, as noted in the comment by user toine.

Sign up to request clarification or add additional context in comments.

1 Comment

That's exactly what i wanted. Thank you :) / I tried subcommands, but it made my script more difficult to use.
2

I would use:

parser = argparse.ArgumentParser()
parser.add_argument('-a', dest='xxx')
parser.add_argument('-b', dest='yyy')
parser.add_argument('-c', dest='zzz')
args = parser.parse_args()

if args.xxx is None:
    args.xxx = 'ABC'
else:
    if args.zzz is not None or args.yyy is not None:
        parser.error('cannot use "b" or "c" with "a"')
if args.zzz is not None and args.yyy is not None:
     command2()
else:
     command1()

Testing for None is the surest way of testing whether the argument was given or not (though the simpler truth test is nearly as good). Internally parse_args keeps a list of seen_actions, but that isn't available to the user. In http://bugs.python.org/issue11588 there's a proposal to provide a testing hook that would have access to this list.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.