4

Is there any way a following code works?

def f1(f2, x):
    return f2(x)

def f2(y, z):
    return y + z

f1(f2(10, ), 20)
output 30

f2 function misses z. So, I want f1 to pass an argument, x, to f2 as z. I will appreciate any help.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
Masa
  • 43
  • 3
  • You have to pass a callable that takes a single argument, created using `def`, `lambda` or `functools.partial`, e.g.: `f1(lambda z: f2(10, z), 20)`. – jonrsharpe Dec 31 '17 at 14:19
  • @jonrsharpe The dupe target here is focussed on passing the arguments from one function to the another functions, however this question is focussed on passing the argument partially while making the call. I don't think this is the right dupe target – Moinuddin Quadri Dec 31 '17 at 14:26
  • OP FYI many of those are also findable by Googling your question title plus `site:stackoverflow.com`, so please do your research before asking in the future. – jonrsharpe Dec 31 '17 at 14:34

2 Answers2

9

Yes, this is what functools.partial is all about:

from functools import partial

f1(partial(f2, 10), 20)

partial takes as input a function f, an an arbitrary number of unnamed and named parameters. It constructs a new function where the unnamed and named parameters are filled in already.

It is somewhat equivalent to:

def partial(func, *partialargs, **partialkwargs):
    def g(*args, **kwargs):
        fargs = partialargs + args
        fkwargs = partialkwargs.copy()
        fkwargs.update(kwargs)
        return func(*farg, **fkwargs)
    return g

But functools will reduce the overhead significantly compared with the above implementation.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
5

Another option showing lambda expressions:

f1(lambda x: f2(10,x), 20)

Partial as shown by @Willem is more suited for your specific problem, but lambda expressions are good to know for flexibility - the expression can become much more complex then just a partial call.

kabanus
  • 24,623
  • 6
  • 41
  • 74