Search code examples
python-3.xfunctiondictionaryargumentskeyword-argument

Python 3 - How to 'convert' a function taking a dict as arguments to one which takes keyword arguments?


I have a function g() with takes a dict as an argument, ex:

>> g({'a':'foo', 'b':'bar', 'c','baz'})
a = foo
b = bar
c = baz

I would like to 'convert' g() or create a new function f() from g() such that it would take positional arguments instead of a dictionary, ex:

>> f(a='foo', b='bar', c='baz')
a = foo
b = bar
c = baz

Background:

  • My goal is to write a small API which will make it easy for users to leverage this core package: https://github.com/fmfn/BayesianOptimization.
  • To use the API, users will have to provide their user-defined-function.
  • My future API will provide the user-defined-function to the core package.
  • The core package expects functions which take positional arguments (not a dict).
  • These user-defined-function are potentially complex and will most likely take many arguments, I would rather tell users to build their functions taking dictionaries as an argument rather than a long list of positional arguments (and do some kind of transformation within my API before invoking the core package).

Or can anyone think of a better way to address this?

Thanks!


Solution

  • I have found a simple way to solve the problem

    Here is a simple function g taking a dict as an argument I want to 'convert':

    >>> def g(my_dict):
            print('a:', str(my_dict['a']))
            print('b:', str(my_dict['b']))
    

    A new function f which takes keyword arguments can easily be created from g:

    >>> def f(**kwargs):
            return g(kwargs)
    

    Let's try f with keyword args:

    >>> f(a='foo', b='bar')
    a: foo
    b: bar
    

    f will not work with positional args:

    >>> f('foo', 'bar')
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-619-505f263ccdf6> in <module>()
    ----> 1 f(1, 2)
    
    TypeError: f() takes 0 positional arguments but 2 were given
    

    Notes:

    1. I originally asked the 'converted' function f to take positional arguments. After doing additional research, I found out I what I meant was keyword arguments. I used the wrong terminology in the question, my apologies.
    2. My attempts with decorators as proposed by @COLDSPEED were only partially successful: I was able to create a function f which seemed to work but somehow the rest of the code was seeing the values it returned as None. Feel free to comment if you have an explanation.