Python: как создать указатель на функцию с заданным аргументом? - PullRequest
3 голосов
/ 18 февраля 2011

Моя проблема:

Учитывая следующее:

def foo(a,b)

Я пытаюсь вызвать функцию Python 'map', передавая список для 'a', но использую установленное значение для 'b.'

Другим важным фактом является то, что «b» - это пользовательский ввод, и поэтому я не могу использовать синтаксис:

def foo(a,b='default value')

Я хочу, чтобы мой вызов 'map' выглядел так:

map(foo_wrapper,list_for_a)

где 'foo_wrapper' - это некоторая функция, которая принимает 'a', но использует указанный пользователем 'b.'

Я не знаю, могут ли указатели функций указываться таким образом, и подозреваю, что они не могут.

Мое решение этой проблемы использует глобальные переменные, поэтому, если есть более элегантный способ, а вышесказанное невозможно, я отмечу это как ответ.

Вот мое решение в двух словах:

b = ''
def foo(a,b):
  print b,a

def foo_wrapper(a):
  foo(a,b)

def main():
  if sys.argv[1]:
    a = ['John', 'Jacob', 'Jingle all the way']
    global b
    b = sys.argv[1]
    map(foo_wrapper,a)

Там может быть опечатка или два в выше; Я упрощаю проблему из того, что мне действительно нужно сделать.

Спасибо за ответы!

Ответы [ 3 ]

7 голосов
/ 18 февраля 2011

Вы хотите что-то похожее на карри. Вы можете просто использовать лямбда здесь:

map(lambda x: f(x,3), a)
7 голосов
/ 18 февраля 2011

Вы можете использовать functools.partial() для этой цели:

from functools import partial

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

x = range(10)
print map(partial(f, b=3), x)

печать

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
1 голос
/ 18 февраля 2011

Использовать понимание списка или выражение генератора

[f(x, your_set) for x in your_list]

Если в результате вам не нужен список, а просто вычисляется ленивый итератор, вы можете использовать выражение генератора (или если вы имели в виду карту Python 3).

(f(x, your_set) for x in your_list)

Edit:

Для ваших функций это будет:

L = ['John', 'Jacob', 'Jingle all the way']
[foo(a, b=b) for a in L]

Понимания списка являются синтаксическим сахаром, заменяющим использование map на lambda. Если у вас есть одно из следующего:

L2 = map(lambda arg: f(arg) + arg, L1)
L2 = map(lambda (x,y): x + y, L1)
L2 = map(lambda <arg>: <expression>, L1)

Они могут быть переписаны как списки:

L2 = [f(arg) + arg for arg in L1]
L2 = [x + y for x, y in L1]
L2 = [<expression> for <arg> in L1]

Выражения генератора аналогичны, но вместо списка они возвращают ленивый итератор и пишутся с символами скобок вместо квадратных скобок. (И поскольку map в Python 3 изменен на не возвращать списки, то его эквивалентом является выражение генератора.) Иногда список не нужен, например, когда вы хотите сделать:

','.join(map(lambda x: x.upper(), L))

Эквивалентное понимание списка:

','.join([x.upper() for x in L])

Но вам на самом деле не нужен список, поэтому вы можете просто сделать:

','.join(x.upper() for x in L)
...