Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use function/method defaults instead of argparse defaults

Tags:

python

When using argparse, I've not found an elegant/DRY way to use the function/method defaults instead of the defaults passed by argparse.

For example, I have foreign code I am loathe to modify. How do I tell argparse (or elegantly handle after argparse) to use the function defaults if the user does not pass in a clear preference on the command-line?

import argparse

def foreign_func(fav_color="blue"):
    print(fav_color)

clparser = argparse.ArgumentParser()
clparser.add_argument(
    "--color",
    default=None,
    help="Enter color")
clargs = clparser.parse_args()

foreign_func(fav_color=clargs.color)

This will print 'None', instead of "blue"

My default approach is something like:

if clparser.color:
    foreign_func(fav_color=clargs.color)
else:
    foreign_func()

but this seems clunky, especially if there are multiple command-line options.

EDIT: Hi folks, thank you for the fast feedback. To clarify, although it would be nice for argparse to display 'blue' in it's help, that's not my goal.

I'm looking for:

my_prog --color=red
>>> red

my_prog 
>>> blue

With the code above, the program is outputting 'None', not "blue"

like image 397
JS. Avatar asked Oct 29 '25 14:10

JS.


2 Answers

You can use inspect to get the function's default parameter value, and use that as the default in the argparse code.

import argparse
import inspect

def foreign_func(fav_color="blue"):
    print(fav_color)

clparser = argparse.ArgumentParser()
clparser.add_argument(
    "--color",
    default=inspect.signature(foreign_func).parameters['fav_color'].default,
    help="Enter color")
clargs = clparser.parse_args()

foreign_func(fav_color=clargs.color)

Note that this will behave a bit oddly if there is no default in the function (if it's a required parameter). In that case, the default value will be the inspect._empty sentinel value, rather than an actually meaningful value. But your code seems to be assuming that the parameter is always optional, so I'm going with that too.

like image 142
Blckknght Avatar answered Oct 31 '25 05:10

Blckknght


You can use a dictionary to specify your arguments by name; if a name is missing, that parameter will use its default. Example:

def func(a=1,b=2):
    print("a=",a,"b=",b)

func()
func(**{})
func(**{'a':10})

will print

a= 1 b= 2
a= 1 b= 2
a= 10 b= 2
like image 29
Scott Hunter Avatar answered Oct 31 '25 03:10

Scott Hunter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!