I've tried using argparse (and optparse before that) and have had trouble finding a workflow that made me happy. This one is pretty close. It allows you to make defaults for when you call a script on the command line and makes those same defaults available if you import the module. It works like this:
- Make a dictionary with the defaults you want.
- In the function you write that parses the arguments, use the dictionary values as the defaults.
- Merge the defaults dictionary and the arguments dictionary together.
- Return the merged dictionary.
The Gist version is available
here, or you can see it below, too.
#######################################
#!/usr/bin/python3
'''
> python3 args_example.py -h
usage: args_example.py [-h] [-f FIRST_OPTION] [-s SECOND_OPTION]
mandatory_argument
Example argument parser with default values.
positional arguments:
mandatory_argument Not everything can have a default value. This is a
mandatory argument.
optional arguments:
-h, --help show this help message and exit
-f FIRST_OPTION, --first_option FIRST_OPTION
This is the first option. Default:
first_default_value.
-s SECOND_OPTION, --second_option SECOND_OPTION
This is the second option. (Default:
second_default_value)
-t THIRD_OPTION, --third_option THIRD_OPTION
This is the third option. (Default:
third_default_value)
> python3 args_example.py -f "non-default first value" --second_option 'non-default second value' "this is mandatory"
{'first_option': 'non-default first value',
'mandatory_argument': 'this is mandatory',
'second_option': 'non-default second value',
'third_option': 'third_default_value'}
Of course, https://pymotw.com/2/argparse/ is still excellent.
'''
import argparse
import pprint
default_settings = {'first_option': 'first_default_value',
'second_option': 'second_default_value',
'third_option': 'third_default_value'}
def get_args(settings=default_settings):
'''Reads from sys.stdin. Use stdin to get new options, and return options
merged with the default options. Settings is a dictionary. We'll have an
argument (no, you came here for an argument), set two options, and default
one.
'''
parser = argparse.ArgumentParser(description='Example argument parser with default values.')
parser.add_argument('mandatory_argument', help='Not everything can have a default value. This is a mandatory argument.')
parser.add_argument('-f', '--first_option', help='This is the first option. Default: %(default)s.',
default=settings['first_option'])
parser.add_argument('-s', '--second_option', help='This is the second option. (Default: %(default)s)',
default=settings['second_option'])
parser.add_argument('-t', '--third_option', help='This is the third option. (Default: %(default)s)',
default=settings['third_option'])
args = parser.parse_args()
args_settings = vars(args) # everything is easier with a dictionary
#python3.5+
merged_settings_3 = {**settings, **args_settings}
#python2
merged_settings_2 = default_settings.copy()
merged_settings_2.update(args_settings)
merged_settings_brute_force = '''
if args.first_option:
settings['first_option'] = args.first_option
if args.second_option:
settings['second_option'] = args.second_option
if args.third_option:
settings['third_option'] = args.third_option
settings['mandatory_argument'] = args.mandatory_argument
return merged_settings_brute_force
'''
return merged_settings_3
def main():
settings = get_args()
pprint.pprint(settings)
if __name__ == '__main__':
main()