2015-04-09 36 views
5

chcę użyć częściowy z functools częściowo zastosować drugi argument funkcji jest, wiem, że to jest łatwe do zrobienia z lambda zamiast częściowe następującojak częściowo zastosować dowolny argument funkcji?

>>> def func1(a,b): 
...  return a/b 
... 
>>> func2 = lambda x:func1(x,2) 
>>> func2(4) 
2 

ale bezwzględnie chcą wykorzystać częściowe tutaj (przez wzgląd uczenia się) więc wymyśliłem to.

>>> def swap_binary_args(func): 
...  return lambda x,y: func(y,x) 
... 
>>> func3 = partial(swap_binary_args(func1),2) 
>>> func3(4) 
2 

Czy możliwe jest rozszerzenie tej strategii do poziomu, gdzie mogę częściowe stosuje się żadnych argumentów w dowolnym miejscu, jak w poniższym pseudocode

>>>def indexed_partial(func, list_of_index, *args): 
...  ###do_something### 
...  return partially_applied_function 

>>>func5=indexed_partial(func1, [1,4,3,5], 2,4,5,6) 

w naszym przypadku można użyć tej funkcji w następujący sposób

>>>func6=indexed_partial(func1, [1], 2) 

Czy możliwe jest indeksowanie częściowe? czy jest coś podobnego do tego, czego nie jestem świadomy? a co ważniejsze, pomysł na indeksowane częściowe ogólnie dobry lub zły pomysł, dlaczego?

To pytanie zostało oznaczone jako możliwego duplikatu Can one partially apply the second argument of a function that takes no keyword arguments? w tej kwestii OP zapytał czy jest możliwe, aby częściowo zastosować drugi argument, ale tu pytam jak gotować funkcję, która może częściowo zastosować dowolną tezę

+4

Czy można uznać tylko za pomocą nazwanych argumentów? 'functools.partial' pozwala na to i tak radzisz sobie z tym w prawdziwym kodzie, choć może nie będzie to pasowało do twojego ćwiczenia. – jwilner

+1

Prawdopodobnie można coś ugotować za pomocą 'inspect.getargspec' i powiązania przy użyciu nazw arg. – tzaman

+0

@jwilner częściowy z argumentem słowa kluczowego byłby praktycznie równoważny z tym, co próbuję osiągnąć, zamiast używać indeksu, powinienem użyć klawiszy. Dzięki :) – k4vin

Odpowiedz

0

Ja też myślę, że o co prosisz, nie można zrobić (łatwo?) Z functools.partial. Prawdopodobnie najlepszym (i najbardziej czytelnym) rozwiązaniem jest użycie partial z argumentami słów kluczowych. Jednak w przypadku, gdy chcesz użyć argumentów pozycyjnych (a więc indeksowane cząstkowych argumentów), tutaj jest możliwe określenie indexed_partial:

def indexed_partial(func, list_of_index, *args): 
    def partially_applied_function(*fargs, **fkwargs): 
     nargs = len(args) + len(fargs) 
     iargs = iter(args) 
     ifargs = iter(fargs) 
     posargs = ((ifargs, iargs)[i in list_of_index].next() for i in range(nargs)) 
     return func(*posargs, **fkwargs) 
    return partially_applied_function