0

I would like to create functions in my Python3 code, making use of data supplied during run-time. I'm stuck on how I can write a function along the lines of

def foo(varname1, varname2):
    return varname1 + varname2

where the strings varname1 and varname2 that give the parameter names are specified as arguments to some constructor function, e.g.:

def makeNewFooFunc(varname1, varname2):
    # do magic
    return foo

fooFunc = makeNewFooFunc('first', 'second')

print(fooFunc(first=1, second=2))
# should return 3

what would be the #do magic step? Is this a job for eval, or is there an alternative?

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
beldaz
  • 4,299
  • 3
  • 43
  • 63
  • 2
    Why are the parameter names important at all? Seems to me you could just work with `**kwargs`, without needing to "generate a function" with that specific signature. – deceze Jul 12 '18 at 07:40
  • @deceze In working with external code that is asking the function and passing the arguments with a dict, so it's the parameter names that matter, not their positions. – beldaz Jul 12 '18 at 08:14
  • The external code is inspecting the function signature and changes its behaviour accordingly? – deceze Jul 12 '18 at 08:14
  • @deceze Not sure. I'm using Flask-Restful, with requires resource classes to have get, post, etc methods that have parameter names that match the name of the variable names in the resource url. – beldaz Jul 12 '18 at 08:20
  • 1
    So it's probably just doing `your_function(**params)`, which means `def your_function(**kwargs)` should work just fine. Also, why can't you simply write those function signatures accordingly by hand? Presumably each of these functions is unique anyway, so why the need to generate them? – deceze Jul 12 '18 at 08:22
  • @deceze Don't want to write by hand as there's about 20 required and I'm trying to keep things DRY. But I see what you mean about the **kwargs approach - that should work fine. – beldaz Jul 12 '18 at 10:22

1 Answers1

2

You don't need to write a function like that. just use **kwargs

def foo_func(**kwargs):
    return sum(kwargs.values())

foo_func(any_name=1, any_name_2=2)

but if you still need to do what you want, you can try

def make_new_func(var_name_1, var_name_2):
    def foo(**kwargs):
        # make sure in kwargs only expected parameters
        assert set(kwargs) == {var_name_1,  var_name_2}
        return kwargs[var_name_1] + kwargs[var_name_2]
    return foo

foo_func = make_new_func('a', 'b')

foo_func(a=1, b=2)