Применить список функций к объекту в Python

есть ли какой-либо чистый способ применить список функций к объекту в Python без понимания лямбда или списка? Как выражение Хаскелла:

map ($ obj) [foo1,foo2]

пример с лямбдой в Python:

response = map(lambda foo:foo(obj),[foo1,foo2]) #fooX:object->Bool

является ли он расширяемым для функций класса?

возможно, что-то от оператора или itertools?

4 ответов


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

как предложено @J. F. Sebastian

>>> from operator import methodcaller
>>> funcs = (lambda x: x + 1, lambda x: x + 2)
>>> obj = 5
>>> map(methodcaller('__call__', obj), funcs)
[6, 7]

вот сумасшедший способ сделать это:

>>> from itertools import starmap, repeat
>>> from types import FunctionType
>>> funcs = (lambda x: x + 1, lambda x: x + 2)
>>> obj = 5
>>> list(starmap(FunctionType.__call__, zip(funcs, repeat(obj))))
[6, 7]

как предложил @AleksiTorhamo

>>> from itertools import repeat
>>> from types import FunctionType
>>> obj = 5
>>> funcs = (lambda x: x + 1, lambda x: x + 2)
>>> map(FunctionType.__call__, funcs, repeat(obj))
[6, 7]

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

def map_funcs(obj, func_list):
    return [func(obj) for func in func_list]

    # I was under the impression that the OP wanted to compose the functions,
    # i.e. f3(f2(f1(f0(obj))), for which the line below is applicable:
    # return reduce(lambda o, func: func(o), func_list, obj)


map_funcs(it, [Buy, Use, Break, Fix])

проблема отсутствует $ оператор, который тривиально определен

def apply(f, a):
    return f(a)

тогда можно сделать карри ($ obj) С частичным в Python, как это: partial(apply, a=obj)

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

map(partial(apply, a=obj), [foo1, foo2]))

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

results = [f(obj) for f in funcList]

Если вам не нужен весь список результатов сразу, но нужно только перебирать элементы по одному за раз, выражение генератора может быть лучше:

genexp = (f(obj) for f in funcList)
for r in genexp:
    doSomething(r)

если ваши функции являются методами, а не основными функциями, есть два способа:

используя связанные методы, в этом случае вы не нужно предоставлять объект вообще при выполнении вызовов функции:

obj = SomeClass()
funcList = [obj.foo1, obj.foo2]
results = [f() for f in funcList]

или с использованием несвязанных методов, которые являются просто регулярными функциями, ожидающими экземпляр класса, в котором они определены в качестве их первого аргумента (условно названного self):

funcList = [SomeClass.foo1, SomeClass.foo2]
obj = SomeClass()
results = [f(obj) for f in funcList]

конечно, если вам не нужно захватывать результаты функции, проще всего просто написать цикл:

for f in funcList:
    f(obj)