Связующие аргументы Python

Как я могу привязать аргументы к методу Python для хранения нулевого функтора для последующего вызова? Похож на boost::bind из C++.

Например:

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

add_5 = magic_function(add, 5)
assert add_5(3) == 8
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
67
0
27 190
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

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)

для python2.6 по крайней мере вы можете использовать from будущее import print_function

Xavier Combelle 19.11.2011 23:06

Я не очень хорошо знаком с 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

это лучший пример, чем принятый ответ, потому что он показывает частичную привязку.

AShelly 25.04.2014 18:24

Так можно определить функторы в 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()

интересный шаблон, но много шаблонов для тривиальных функций.

Dustin Getz 10.11.2008 18:02

Вы можете сократить его до чего-то значительно более простого, в зависимости от ваших реальных вариантов использования. Исходный вопрос не дает никаких указаний о том, как происходит привязка. Без конкретики нужно охватить слишком много оснований.

S.Lott 10.11.2008 18: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

Это тоже сработает:

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

Это не карри. Каррирование предназначено для функций с несколькими аргументами. Карри работает так: Учитывая g = curry(f), у нас есть f(x1,x2,...) = g(x1)(x2)...

Gavin Haynes 22.05.2019 02:43

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

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

Это должен быть принятый ответ. Это питонический способ привязки аргументов к вызываемым объектам

thehouse 14.02.2015 01:41

Вопрос обычно касается связывающих аргументов, но все ответы касаются функций. Если вам интересно, 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

Другие вопросы по теме