如何将参数绑定到Python方法以存储一个用于以后调用的nullary仿函数?与C ++的boost::bind
类似。
例如:
def add(x, y):
return x + y
add_5 = magic_function(add, 5)
assert add_5(3) == 8
答案 0 :(得分:71)
functools.partial
返回一个可调用的包装函数,其中一些或所有参数都被冻结。
import sys
import functools
print_hello = functools.partial(sys.stdout.write, "Hello world\n")
print_hello()
Hello world
以上用法相当于以下lambda
。
print_hello = lambda *a, **kw: sys.stdout.write("Hello world\n", *a, **kw)
答案 1 :(得分:42)
我对boost :: bind并不过分熟悉,但来自partial
的{{1}}函数可能是一个好的开始:
functools
答案 2 :(得分:11)
如果functools.partial
不可用,则可以轻松模拟:
>>> make_printer = lambda s: lambda: sys.stdout.write("%s\n" % s)
>>> import sys
>>> print_hello = make_printer("hello")
>>> print_hello()
hello
或者
def partial(func, *args, **kwargs):
def f(*args_rest, **kwargs_rest):
kw = kwargs.copy()
kw.update(kwargs_rest)
return func(*(args + args_rest), **kw)
return f
def f(a, b):
return a + b
p = partial(f, 1, 2)
print p() # -> 3
p2 = partial(f, 1)
print p2(7) # -> 8
d = dict(a=2, b=3)
p3 = partial(f, **d)
print p3(), p3(a=3), p3() # -> 5 6 5
答案 3 :(得分:9)
lambdas允许您使用较少的参数创建一个新的未命名函数并调用该函数!
>>> def foobar(x,y,z):
... print "%d, %d, %d" % (x,y,z)
>>> foobar(1,2,3) # call normal function
>>> bind = lambda x: foobar(x, 10, 20) # bind 10 and 20 to foobar
>>> bind(1) # print 1, 10, 20
>>> bind = lambda: foobar(1,2,3) # bind all elements
>>> bind() # print 1, 2, 3
https://docs.python.org/2/library/functools.html#functools.partial
如果您打算在函数调用中使用命名参数绑定,这也适用:
>>> from functools import partial
>>> barfoo = partial(foobar, x=10)
>>> barfoo(y=5,z=6)
21
请注意
>>> barfoo(5,6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foobar() got multiple values for keyword argument 'x'
>>> f = partial(foobar, z=20)
>>> f(1,1)
22
答案 4 :(得分:7)
这也可行:
def curry(func, *args):
def curried(*innerargs):
return func(*(args+innerargs))
curried.__name__ = "%s(%s, ...)" % (func.__name__, ", ".join(map(str, args)))
return curried
>>> w=curry(sys.stdout.write, "Hey there")
>>> w()
Hey there
答案 5 :(得分:1)
可以在Python中以这种方式定义Functors。它们是可调用的对象。 “绑定”仅设置参数值。
class SomeFunctor( object ):
def __init__( self, arg1, arg2=None ):
self.arg1= arg1
self.arg2= arg2
def __call___( self, arg1=None, arg2=None ):
a1= arg1 or self.arg1
a2= arg2 or self.arg2
# do something
return
您可以执行
之类的操作x= SomeFunctor( 3.456 )
x( arg2=123 )
y= SomeFunctor( 3.456, 123 )
y()
答案 6 :(得分:0)
该问题通常询问有关绑定参数的问题,但所有答案均与函数有关。如果您想知道,partial
还可以与类构造函数一起使用(即使用类而不是函数作为第一个参数),这对于工厂类很有用。您可以按照以下步骤进行操作:
from functools import partial
class Animal(object):
def __init__(self, weight, num_legs):
self.weight = weight
self.num_legs = num_legs
animal_class = partial(Animal, weight=12)
snake = animal_class(num_legs = 0)
print(snake.weight) # prints 12