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)
我对boost :: bind并不过分熟悉,但是partial
函数functools
可能是一个好的开始:
>>> from functools import partial >>> def f(a, b): ... return a+b >>> p = partial(f, 1, 2) >>> p() 3 >>> p2 = partial(f, 1) >>> p2(7) 8
如果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
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 "", line 1, in TypeError: foobar() got multiple values for keyword argument 'x' >>> f = partial(foobar, z=20) >>> f(1,1) 22
这也可行:
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