I have a class & method, each with several arguments: my_class(a,b,c).my_method(d,e,f)
and I'd like to be able to only change a single argument, while holding the others constant.
Constantly copy-pasting the other constant arguments seems bad, so I'd like to create a new object wrapper_fct
where I reference my_class
but only provide the one argument I want to change, b
, without always having to specify the remaining arguments. How would wrapper_fct()
look like?
For example, wrapper_fct(my_class, b1)
would return my_class(a,b1,c).my_method(d,e,f)
, wrapper_fct(my_class, b2)
would return my_class(a,b2,c).my_method(d,e,f)
.
Here's an example in practice:
Loop through just the variable b
and evaluate several classes/methods for each new instance of b
, and append the results in a list.
I can currently do this in a for
loop:
mylist1 = [] # init lists (append results here)
mylist2 = []
mylist2 = []
for b in [1,2,3,4,5]:
mylist1.append( my_class1(a,b,c).my_method(d,e,f) )
mylist2.append( my_class2(a,b,c).my_method(d,e,f) )
mylist3.append( my_class3(a,b,c).my_method(d,e,f) )
...
But it seems better to create a function loop_through_B()
and use the wrapper_fct(my_class,b)
as specified above. Not sure if it's the ideal solution, but maybe something like:
def loop_through_B(input_class, b_values = [1,2,3,4,5])
mylist = []
for b in b_values:
mylist.append( wrapper_fct(input_class,b) )
return mylist
loop_through_B(my_class1) # would I also have to specify the method here as well?
loop_through_B(my_class2)
loop_through_B(my_class3)
Extra Question: how would I add the ability to vary method arguments, or even multiple class & method arguments?
After @chepner pointed me in the right direction, I think the best solution is to use the lambda
function:
wrapper_fct = lambda b: my_class1(a,b,c).my_method(d,e,f)
In this case, I can vary b
as much as I want while holding the class arguments a,c
, and method arguments d,e,f
constant. Note that with lambda
functions, I can also vary the method arguments and/or the class arguments. For example:
wrapper_fct_multiple = lambda b, e: my_class1(a,b,c).my_method(d,e,f)
It is also possible to do this with functools.partial
, but it's not obvious to me how I would specify both class & method arguments with functools.
Anyway, here is the solution implementation using lambda
:
# define the "wrapper function" outside the loop
wrapper_fct = lambda b: my_class1(a,b,c).my_method(d,e,f)
# define the function I want to use to loop through B:
def loop_through_B(class_wrapper, b_values)
mylist = []
for b in b_values:
mylist.append( class_wrapper(b) )
return mylist
# run:
loop_through_B(wrapper_fct, b_values=[1,2,3,4,5])
# Can make additional wrapper_fct2, wrapper_fct3, for my_class2, my_class3 ...