10

All,

def a(p):
    return p+1

def b(func, p):
    return func(p)

b(a,10)   # 11

here I do not want the result "11" actually, what I want is a function object with the parameter has been binded, let's name it c.

when I use c() or something alike, it will give me the result 11, possible?

Thanks!

user478514
  • 3,859
  • 10
  • 33
  • 42

6 Answers6

15

The functools module provides the partial function which can give you curried functions:

import functools

def a(p):
    return p+1

def b(func, p):
    return functools.partial(func, p)

c = b(a,10)
print c() # >>  11

It can be used to apply some parameters to functions, and leave the rest to be supplied:

def add(a,b):
    return a+b

add2 = functools.partial(add, 2)
print add2(10)  # >> 12
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
9

you can also use the functools module


import functools

def add(a,b):
    return a+b

>> add(4,6)

10
>> plus7=functools.partial(add,7)
>>plus7(9)
16

 
mossplix
  • 3,783
  • 2
  • 26
  • 31
6

The only way to do that, is to wrap it in a lambda:

c = lambda : b(a,10)
c() # 11

Though if you're going to name it anyway, that doesn't really buy you anything compared to

def c():
  b(a,10)
sepp2k
  • 363,768
  • 54
  • 674
  • 675
2

Though I am not sure of the use, Use lambda:

>>> def a(p): return p+1
... 
>>> def b(func, p):
...     g = lambda p: func(p) 
...     return g
... 
>>> 
>>> b(a, 4)
<function <lambda> at 0x100430488>
>>> k = b(a, 4)
>>> k(5)
6
pyfunc
  • 65,343
  • 15
  • 148
  • 136
1

Both functool and returning a function object work. A small test I ran showed that returning a function object method is slightly faster.

import time
import functools

#####################################
## Returning function object method
#####################################

def make_partial(n):
    def inc(x):
        return x+n
    return inc

start = time.clock()
for i in range(10000):
    g = make_partial(i)
print("time taken to create 10000: {}".format(time.clock() - start))

b = 0

start = time.clock()
for i in range(10000):
    b += g(i)
print("time taken to use it 10000 times: {}".format(time.clock() - start))


#####################################
## Using functools method 
#####################################

def make_partial2(x,n):
    return x + n

start = time.clock()
for i in range(10000):
    g = functools.partial(make_partial2,i)
print("time taken to create 10000: {}".format(time.clock() - start))

b = 0

start = time.clock()
for i in range(10000):
    b += g(i)
print("time taken to use it 10000 times: {}".format(time.clock() - start))

Which resulted in:

time taken to create 10000: 0.0038569999999999993
time taken to use it 10000 times: 0.0030769999999999964
time taken to create 10000: 0.004314000000000151
time taken to use it 10000 times: 0.00390299999999999

Showing it's both faster to make and call. (Albeit not by much)

m4p85r
  • 402
  • 2
  • 17
0

You can create another function that calls the your function with the parameter that you want.

def old_function(x,y):
    return x+y

def bound_parameter_function(x):
    return old_function(x,10)

Of course, if you need to create such functions on the fly, you can write another function that does the job for you:

def parameter_bound(f, parm_to_bind):
    def ret(y):
        return f(parm_to_bind,y)
     return ret

new_func=parameter_bound(old_function,10)
new_func(1)
MAK
  • 26,140
  • 11
  • 55
  • 86