вернуть объект функции с параметром binded? - PullRequest
5 голосов
/ 28 октября 2010

Все,

def a(p):
    return p+1

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

b(a,10)   # 11

здесь я не хочу, чтобы результат "11" на самом деле, я хочу, чтобы объект функции с параметром был связан, назовем его c.

когда я использую c() или что-то подобное, это даст мне результат 11, возможно?

Спасибо!

Ответы [ 6 ]

8 голосов
/ 28 октября 2010

Модуль functools обеспечивает функцию partial, которая может давать вам функции карри:

import functools

def a(p):
    return p+1

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

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

Может использоваться для применения некоторых параметров к функциям, а остальные должны быть предоставлены:

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

add2 = functools.partial(add, 2)
print add2(10)  # >> 12
8 голосов
/ 28 октября 2010

Вы также можете использовать модуль functools


import functools

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

>> add(4,6)

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

 
6 голосов
/ 28 октября 2010

Единственный способ сделать это, это обернуть его в лямбду:

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

Хотя, если вы все-таки назовете его, это ничего не даст вам по сравнению с

def c():
  b(a,10)
2 голосов
/ 28 октября 2010

Хотя я не уверен в использовании, используйте лямбду:

>>> 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
0 голосов
/ 26 сентября 2017

Оба functool и возвращающие объект функции работают. Небольшой тест, который я выполнил, показал, что возвращение метода объекта функции немного быстрее.

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))

Что привело к:

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

Показывает, что звонить и звонить быстрее. (Хотя и ненамного)

0 голосов
/ 28 октября 2010

Вы можете создать другую функцию, которая будет вызывать вашу функцию с нужным параметром.

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

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

Конечно, если вам нужно создавать такие функции на лету, вы можете написать другую функцию, которая делаетработа для вас:

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)
...