argparse, tell if arg was defaulted

Neal Becker ndbecker2 at gmail.com
Tue Mar 15 18:42:53 EDT 2011


Robert Kern wrote:

> On 3/15/11 12:46 PM, Neal Becker wrote:
>> Robert Kern wrote:
>>
>>> On 3/15/11 9:54 AM, Neal Becker wrote:
>>>> Is there any way to tell if an arg value was defaulted vs. set on command
>>>> line?
>>>
>>> No. If you need to determine that, don't set a default value in the
>>> add_argument() method. Then just check for None and replace it with the
>>> default value and do whatever other processing for the case where the user
>>> does not specify that argument.
>>>
>>> parser.add_argument('-f', '--foo', help="the foo argument [default: bar]")
>>>
>>> args = parser.parse_args()
>>> if args.foo is None:
>>>       args.foo = 'bar'
>>>       print 'I'm warning you that you did not specify a --foo argument.'
>>>       print 'Using default=bar.'
>>>
>>
>> Not a completely silly use case, actually.  What I need here is a combined
>> command line / config file parser.
>>
>> Here is my current idea:
>> -----------------------------
>>
>> parser = OptionParser()
>> parser.add_option ('--opt1', default=default1)
>>
>> (opt,args) = parser.parse_args()
>>
>> import json, sys
>>
>> for arg in args:
>>      print 'arg:', arg
>>      d = json.load(open (arg, 'r'))
>>      parser.set_defaults (**d)
>>
>> (opt,args) = parser.parse_args()
>> -----------------------
>>
>> parse_args() is called 2 times.  First time is just to find the non-option
>> args,
>> which are assumed to be the name(s) of config file(s) to read.  This is used
>> to
>> set_defaults.  Then run parse_args() again.
> 
> I think that would work fine for most cases. Just be careful with the argument
> types that may consume resources. E.g. type=argparse.FileType().
> 
> You could also make a secondary parser that just extracts the config-file
> argument:
> 
> [~]
> |25> import argparse
> 
> [~]
> |26> config_parser = argparse.ArgumentParser(add_help=False)
> 
> [~]
> |27> config_parser.add_argument('-c', '--config', action='append')
> _AppendAction(option_strings=['-c', '--config'], dest='config', nargs=None,
> const=None, default=None, type=None, choices=None, help=None, metavar=None)
> 
> [~]
> |28> parser = argparse.ArgumentParser()
> 
> [~]
> |29> parser.add_argument('-c', '--config', action='append')  # For the --help
> string.
> _AppendAction(option_strings=['-c', '--config'], dest='config', nargs=None,
> const=None, default=None, type=None, choices=None, help=None, metavar=None)
> 
> [~]
> |30> parser.add_argument('-o', '--output')
> _StoreAction(option_strings=['-o', '--output'], dest='output', nargs=None,
> const=None, default=None, type=None, choices=None, help=None, metavar=None)
> 
> [~]
> |31> parser.add_argument('other', nargs='*')
> _StoreAction(option_strings=[], dest='other', nargs='*', const=None,
> default=None, type=None, choices=None, help=None, metavar=None)
> 
> [~]
> |32> argv = ['-c', 'config-file.json', '-o', 'output.txt', 'other',
> |'arguments']
> 
> [~]
> |33> known, unknown = config_parser.parse_known_args(argv)
> 
> [~]
> |34> known
> Namespace(config=['config-file.json'])
> 
> [~]
> |35> unknown
> ['-o', 'output.txt', 'other', 'arguments']
> 
> [~]
> |36> for cf in known.config:
> ...>     # Load d from file.
> ...>     parser.set_defaults(**d)
> ...>
> 
> [~]
> |37> parser.parse_args(unknown)
> Namespace(config=None, other=['other', 'arguments'], output='output.txt')
> 
> 

nice!




More information about the Python-list mailing list