0

I have many different methods all in different classes with different function signatures that all have the same set of default parameters but usually have different non-default parameters. I wanted to make my code more loosely coupled by having these default parameters reference a variable instead of being hardcoded in each signature so in the case I wanted to change one of the defaults I wouldn't have to visit each method. For example, say I have a dictionary containing {'param1': True, 'param2': False, 'param3': 100} I would want to make each pair act as a default parameter. In theory, it would look something like this:

#So this
defaultParams = {'param1': True, 'param2': False, 'param3': 100}
def func(*args, **defaultParams) #thinking that you could 'spread' the default params into the function based off the var. Obv wouldn't work but that's the functionality I would want

#would be equivalent to this
def func(*args, param1=True, param2=False, param3=100)

#but would NOT look like this as I don't want to have to lookup an item to reference it:
def func(*args, kwargs=defaultParams)

Im wondering if this is possible in python and if it isn't if there is a design pattern that would accommodate this problem.

Thanks

4
  • 1
    I'd suggest encapsulating the parameters in some kind of options/config object rather than using kwargs. Then you can specify the defaults in that class's constructor. Commented May 19, 2022 at 0:11
  • Does this answer your question? Is it possible to change a function's default parameters in Python? Commented May 19, 2022 at 0:14
  • 1
    Make your configuration object a dataclass. Preferably a frozen one. It's like a dictionary but you can give it a docstring and it makes type-checking easier if you go down that route. Commented May 19, 2022 at 0:16
  • 1
    To be clear: the idea is that multiple methods have a common set of parameters with the same names, and each method should have the same default value for the same given parameter, as each other method; and you want to be able to update all the default values in a common place? That sounds like exactly the job for some kind of data structure; why don't you want those lookups? You gain encapsulated data that you can then pass around as a unit. Commented May 19, 2022 at 0:18

2 Answers 2

1

You can't do this in the parameter list, but you can merge with the defaults inside the function.

defaultParams = {'param1': True, 'param2': False, 'param3': 100}

def func(**kwargs):
    kwargs = defaultParams | kwargs
Sign up to request clarification or add additional context in comments.

Comments

1

You could do this inside each function in question by doing dictionary updates:

def func(*args, **kwargs):
  kw = dict(defaultParams) | kwargs
  # ... proceed with computation

If you wanted to do this on many functions, you could potentially use a decorator:

def with_defaults(f):
  def wrapper(*args, **kwargs):
    kw = dict(defaultParams) | kwargs
    return f(*args, **kw)
  return wrapper

@with_defaults
def func(*args):
  # ...

I also feel like it's worth pointing out that this sort of pattern can be quite risky, given that dictionaries in Python are mutable -- if something changed defaultParams somewhere, then suddenly the behaviors of all your functions would change. You might mitigate this by making defaultParams a tuple of key-value ordered pairs. (Or, as others have suggested, using a dataclass, but I'm not sure if you'd then lose the dictionary update semantics.)

In addition, the signature information of the functions in question would be off. Probably there's a way to address this using some metaprogramming magic, but it would start to get complex quickly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.