338

I would like to have a optional argument that will default to a value if only the flag is present with no value specified, but store a user-specified value instead of the default if the user specifies a value. Is there already an action available for this?

An example:

python script.py --example
# args.example would equal a default value of 1
python script.py --example 2
# args.example would equal a default value of 2

I can create an action, but wanted to see if there was an existing way to do this.

2 Answers 2

458
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--example', nargs='?', const=1, type=int)
args = parser.parse_args()
print(args)

% test.py 
Namespace(example=None)
% test.py --example
Namespace(example=1)
% test.py --example 2
Namespace(example=2)

  • nargs='?' means 0-or-1 arguments
  • const=1 sets the default when there are 0 arguments
  • type=int converts the argument to int

If you want test.py to set example to 1 even if no --example is specified, then include default=1. That is, with

parser.add_argument('--example', nargs='?', const=1, type=int, default=1)

then

% test.py 
Namespace(example=1)
Sign up to request clarification or add additional context in comments.

3 Comments

How to do this with strings? I have a dilemma with differentiation of "" (empty string as default) and "" (empty string as entered by user). In the code for now I'm using the default and since I need to do some ops, I have something like this self.foo = (args.bar or some_else_source).upper(). It will break on None object AFAIUC.
BE CAREFUL; if you try to have positional args afterwards, the first position arg will become the value for --example (if it doesn't have an explicit one). Just spent 10 minutes debugging that!
is there a way to make it accept an optional int and still distinguish a positional string argument?
112

The difference between:

parser.add_argument("--debug", help="Debug", nargs='?', type=int, const=1, default=7)

and

parser.add_argument("--debug", help="Debug", nargs='?', type=int, const=1)

is thus:

myscript.py => debug is 7 (from default) in the first case and "None" in the second

myscript.py --debug => debug is 1 in each case

myscript.py --debug 2 => debug is 2 in each case

4 Comments

Excellent way to describe this difference
There is a contradiction between your answer and the previous answer... According to previous answer: myscript.py --debug should bring 7
You’re welcome to test the code for yourself. If I’ve made a mistake it’s helpful for us all. However, I believe I have correctly described the results of my testing. Test.py gives 7 because no —debug argument was provided so the default value is used. Test.py —debug gives 1, the value set by const.
There may be issues with running code, but this answer does correctly demonstrate how to assign default values with argparse, which is the crux of the question.

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.