0

Suppose I have the following function

def f(x,y,**kwargs):
    if 'z' in kwargs:
        z = kwargs['z']
    else:
        z = 0
    print(x + y + z)

which takes two arguments and an optional keyword argument. I now want to get a function g that works just as f but for which the value of z is predetermined. Hence, I could do the following

def g(x,y):
    z = 3 
    f(x,y, z = 3)

But what can I do if I do not know the number of non-keyword arguments that f takes. I can get the list of these arguments by

args = inspect.getargspec(f)[0]

But, if I now define g as

g(args):
    z = 3
    f(args, z=z)

this of course does not work as only one mandatory argument is passed to f. How do I get around this? That is, if I have a function that takes keyword arguments, how do I define a second function exactly the same expect that the keyword arguments take predeterminde values?

lbf_1994
  • 239
  • 2
  • 9

2 Answers2

1

You have a few options here:

  1. Define g with varargs:

    def g(*args):
        return f(*args, z=3)
    

    Or, if you need keyword arguments as well:

    def g(*args, **kwargs):
        kwargs['z'] = 3
        return f(*args, **kwargs)
    
  2. Use functools.partial:

    import functools
    
    g = functools.partial(f, z=3)
    

    See also this related question: Python Argument Binders.

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • Thanks for your answer, but it's not quite yet what I was hoping for. In my first example, where the number of arguments were known, the resulting function g had no varargs or keyword arguments. In your first example however you have varargs and in your second example you have kwargs. – lbf_1994 Jun 04 '18 at 10:34
  • @lbf_1994 Why do you care whether `g` has varargs or not? If you pass too few or too many arguments, it'll still throw an error as it should. – Aran-Fey Jun 04 '18 at 11:19
0

You can use functools.partial to achieve this

import functools
f = functools.partial(f, z=2)

# the following example is the usage of partial function f
x = f(1, 2)
y = f(1, 2, k=3)
z = f(1, 2, z=4)
Ballack
  • 906
  • 6
  • 12