Связующих Аргументов В Python
Как я могу привязать аргументы к методу Python для хранения нулевого функтора для последующего вызова? Похож на C++'ы boost::bind
.
например:
def add(x, y):
return x + y
add_5 = magic_function(add, 5)
assert add_5(3) == 8
6 ответов:
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)
Если
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
лямбды позволяют создать новую безымянную функцию с меньшим количеством аргументов и вызвать функцию!
>>> 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
edit
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
Это тоже сработает:
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
функторы могут быть определены таким образом в Python. Это вызываемые объекты. "Привязка" просто устанавливает значения аргументов.
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()