2010-10-28 4 views
4

Tous,renvoie un objet fonction avec le paramètre lié?

def a(p): 
    return p+1 

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

b(a,10) # 11 

ici, je ne veux pas le résultat « 11 » en fait, ce que je veux est un objet de fonction avec le paramètre a été binded, Appelons-c.

lorsque j'utilise c() ou quelque chose de semblable, il me donnera le résultat 11, possible?

Merci!

Répondre

5

le module functools fournit la fonction partial qui peut vous donner les fonctions curryfiées:

import functools 

def a(p): 
    return p+1 

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

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

Il peut être utilisé pour appliquer des paramètres aux fonctions, et laisser le reste à fournir:

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

add2 = functools.partial(add, 2) 
print add2(10) # >> 12 
+0

pouvez-vous expliquer pourquoi 2 et 10 peuvent être séparés? – user478514

+0

functools.partial prend une fonction et un certain nombre d'arguments, puis retourne une fonction qui prend le reste des arguments. –

+0

partial ne retourne pas une fonction mais un objet partiel, donc si vous voulez faire f (c) avec f attend une fonction qui échouera! – agemO

5

La seule façon de le faire, est de l'envelopper dans un lambda:

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

Bien que si vous allez nommer de toute façon, ne pas vraiment acheter quoi que ce soit par rapport à

def c(): 
    b(a,10) 
+0

merci, en fait j'aurai une liste de b (a, x), je veux utiliser [x() pour x dans la liste] pour obtenir le résultat dans un aller. – user478514

1

Bien que je ne suis pas sûr de l'utilisation, l'utilisation 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 
0

Vous pouvez créer une autre fonction qui appelle votre fonction avec le paramètre que vous voulez.

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

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

Bien sûr, si vous avez besoin de créer de telles fonctions à la volée, vous pouvez écrire une autre fonction qui fait le travail pour vous:

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

vous pouvez également utiliser le module functools

 

import functools 

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

>> add(4,6) 

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

 
0

Les deux functool et le retour d'un travail d'objet fonction. Un petit test que j'ai exécuté a montré que le retour d'une méthode d'objet fonction est légèrement plus rapide.

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

Ce qui a donné lieu à:

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 

est à la fois montrer plus rapide à faire et appeler. (Quoique pas beaucoup)

Questions connexes