Home > Software engineering >  Pythonic way to override variables in function with arguments
Pythonic way to override variables in function with arguments

Time:03-15

New to python and have situation like this:

myfun.py:

def fun(x, ...):
   par1 = ...
   par2 = ...
   ... # many pars
   parn = ...
return #*long and complicated function of all the pars and x inputs*

Sometimes I'd like to modify one or more of the pars without modifying myfun.py itself. I know I could:

  1. Define every par as an argument to fun and give it a default value
  2. Make a dictionary par_dict = {'par1': ..., ...} then wherever I have par1 in my return code replace it with par_dict['par1']. Then use par_dict.update() to take a dictionary argument and update my pars.

Any clean and compact alternatives to these options? I'd like something like this:

fun(x_in, par10=5)
# output uses 5 where par10 occurs in the function, in other words the argument to the function overrides the values set inside the function.

Thank you.

CodePudding user response:

The most pythonic way I find is something like this: First you define the function, such as

def fun(x, *, par1=1, par2=2, ..., parn=999):
    return # function using all params

The function has its default settings, with the predefined values for the parameters. The * as second argument is to prevent the use of positional arguments for further than the x variable.

Then you may use configurable dictionaries to alter the params:

params = {
    'par1': 10,
    'par2': 20,
    ...
    'parn': 0}

fun(X, **params)

The **params distributes the variables declared in the dictionary to the input parameters in the function.

EDIT It is also possible to use nested functions, like this:

def outer(par1=1, par2=2, ..., parn=999):
    def inner(x):
        return # function using x and pars...
    return inner

Notice that the params of the outer function don't need to have default values. Then you "instance" the function, using it with any set of new params.

params = {...}  # like the previous example
fun = outer(**params)
fun(X)

You can use outer to create different functions, that behaves as the params you input, for instance:

params1 = {...}
fun1 = outer(**params1)

params2 = {...}
fun2 = outer(**params2)

a = fun1(X)
b = fun2(X)

In this case a and b are different.

  • Related