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
CodePudding user response:
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
CodePudding user response:
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.