Python argparse: default value or specified value
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 argumentsconst=1
sets the default when there are 0 argumentstype=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, withparser.add_argument('--example', nargs='?', const=1, type=int, default=1)
then% test.py
Namespace(example=1)
Why does argparse include default value for optional argument even when argument is specified?
The logic for handling defaults is to insert all defaults into the namespace
at the start of parsing. Then let parsing replace them. Then at the end of parsing there's a complicated piece of logic:
for each value in the namespace
if it is a string and equals the default
evaluate the string (with `type`) and put it back
For ordinary store
actions this works fine, and lets you provide defaults as strings or any value of your choice.With append
this produces your unexpected value. It puts the ['all']
on the namespace, and then appends the new values to that. Since your nargs
is '+', it appends a list, resulting in that mix of string and lists.
The append
action cannot tell whether it is appending the new value to a list provided by default
or a list that's the result of several previous appends
. With a None
default it will create an empty list, and append to that.
While this doesn't perform as you expected, it actually gives you a lot of control.
The simplest way around this is to leave the default as None
. After parsing, just check if this attribute is None
, and if so, replace it with your ['all']
. It is not evil or contrary to the design intentions of argparse
developers. Somethings are easier after all the input has been parsed.
The issue has been raised on Python bug/issues, http://bugs.python.org/issue16399, and probably here on SO before. But I suspect the best a patch can do is to add a note to the documentation, similar to this one from optparse
:
See the bug/issue for ideas about writing your own append Action subclass."The append action calls the append method on the current value of the option. This means that any default value specified must have an append method. It also means that if the default value is non-empty, the default elements will be present in the parsed value for the option, with any values from the command line appended after those default values".
Python argparse default string value
You can use nargs='?'
for this:
parser.add_argument('-o', '--output',
nargs='?', default=None, const='my_default_location')
If not present, it will produce the default
value, if present but without a value it'll use const
, otherwise it'll use the supplied value. Also read through the other examples in the docs, there's a sample for an optional output file which could be useful.
Use an ArgumentParser argument as a default value of another argument
parse_known_args
parse the argument and send it to another argument.
pin_file_path= None
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormater)
parser.add_argument('-p', '--pin_file_path', help = "the directory of the given pin file", default = os.getcwd())
args, remaining = parser.parse_known_args()
parser.add_argument('--option2', default=args.pin_file_path)
args = parser.parse_args()
How to differentiate between default value and user given value in argparse, python?
Then you don't want to supply a default value; make the parameter optional (e.g. Argparse optional positional arguments? ), and then explicitly check for its presence or absence in the resulting Namespace object and do the appropriate thing in your code logic - presumably, check for a value in previous usage and then supply a default as a last resort. (Think of default values as a shortcut logic to handle the absence of the value; you need more complicated logic, so better to replace that system than to try to work around it.)if a user didn't input any value to the optional argument, I want to take the value from previous usage (if any). So, I want to determine whether the value came as a default value or user given value.
Argparse: Way to include default values in '--help'?
Use the argparse.ArgumentDefaultsHelpFormatter
formatter:
parser = argparse.ArgumentParser(
# ... other options ...
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
To quote the documentation:The other formatter class available, ArgumentDefaultsHelpFormatter
, will add information about the default value of each of the arguments.
Note that this only applies to arguments that have help text defined; with no help
value for an argument, there is no help message to add information about the default value to.The exact output for your scan-time option then becomes:
--scan-time [SCAN_TIME]
Wait SCAN-TIME seconds between status checks.
(default: 5)
Argparse append action with default value only if argument doesn't appear
There's a bug/issue discussing this behavior. I wrote several posts to that.
https://bugs.python.org/issue16399 argparse: append action with default list adds to list instead of overriding
For now the only change is in documentation, not in behavior.
All defaults are placed in the namespace at the start of parsing. For ordinary actions, user values overwrite the default. But in the append case, they are just added to what's there already. It doesn't try to distinguish between values placed by the default, and previous user values.
I think the simplest solution is to leave the default as is, and check after parsing for None
or empty list (I don't recall which), and insert your default. You don't get extra points for doing all the parsing in argparse
. A bit of post parsing processing is quite ok.
Related Topics
What's the Difference Between Subprocess Popen and Call (How to Use Them)
What Is the Inverse Function of Zip in Python
How to Get All the Request Headers in Django
Opencv Python: Draw Minarearect ( Rotatedrect Not Implemented)
Python Element-Wise Tuple Operations Like Sum
How May I Override the Compiler (Gcc) Flags That Setup.Py Uses by Default
Generating PDF-Latex with Python Script
Python - Email Header Decoding Utf-8
Should I Be Adding the Django Migration Files in the .Gitignore File
Asyncio: How to Cancel a Future Been Run by an Executor
Cheap Way to Search a Large Text File for a String
Pandas - Add New Column to Dataframe from Dictionary
How to Convert an Int to a Hex String
Stop Matplotlib Repeating Labels in Legend
How to Build a Systemtray App for Windows
Regex for Existence of Some Words Whose Order Doesn't Matter