I'm trying to initialize a collection of function calls based on input data, but not sure how to do this. The ideas is like below. I expect the local_v will stay unchanged once being defined. Can anyone shed some light how to deal with this or where to start with?
ls = [1,2]
for v in ls:
def fn():
local_v = v
print(local_v)
locals()[f'print{v}'] = fn
print1() # output: 2 expect to be 1
print2() # output: 2
CodePudding user response:
Better to store the functions in a dictionary rather than changing locals
, which is likely to get confusing. You could use a nested function like this:
def function_maker(v):
def fn():
print(v)
return fn
print_functions = {v: function_maker(v) for v in [1, 2]}
print_functions[1]()
print_functions[2]()
Alternatively use functools.partial
from functools import partial
def fn(v):
print(v)
print_functions = {v: partial(fn, v) for v in [1, 2]}
CodePudding user response:
If you want v
to be tied to the local context, you'll have to pass it inside the function. You will also need to return a callable to print
rather than using the print
function directly, or else you will find that print1
and print2
will be None
. And at this point, there is no need to redefine fn
at each iteration of the loop. Something like that will work:
ls = [1, 2]
def fn(v):
return lambda: print(v)
for v in ls:
locals()[f'print{v}'] = fn(v)
print1() # output: 1
print2() # output: 2
Just to try to be clearer: invoking print1()
does not call fn(1)
, it calls the lambda that returned by fn(1)
.