13

Python 3.2 documentation dotyczy Collin Winter's functional module który zawiera funkcję compose:komponować funkcji i moduł funkcjonalny

komponować() realizuje funkcję kompozycji funkcji. W innych słowach zwraca on owijkę wokół zewnętrznych i wewnętrznych podpórek, na przykład , że wartość zwracana z wewnętrznej jest podawana bezpośrednio na zewnątrz.

Niestety ten moduł nie został zaktualizowany od lipca 2006; Zastanawiam się, czy jest dostępny jakiś zamiennik.

Na razie potrzebuję tylko funkcji compose. Czy następująca oryginalna definicja functional.compose jest nadal dobra dla Pythona 3?

def compose(func_1, func_2, unpack=False): 
    """ 
    compose(func_1, func_2, unpack=False) -> function 

    The function returned by compose is a composition of func_1 and func_2. 
    That is, compose(func_1, func_2)(5) == func_1(func_2(5)) 
    """ 
    if not callable(func_1): 
     raise TypeError("First argument to compose must be callable") 
    if not callable(func_2): 
     raise TypeError("Second argument to compose must be callable") 

    if unpack: 
     def composition(*args, **kwargs): 
      return func_1(*func_2(*args, **kwargs)) 
    else: 
     def composition(*args, **kwargs): 
      return func_1(func_2(*args, **kwargs)) 
    return composition 

Ta SO question jest nieco spokrewniona; pyta, czy Python powinien obsługiwać specjalną składnię dla compose.

+0

Python 3 robi ot oddać 'callable' wybudowany w kluczowych - zwykle jest zastąpiony' hasattr (obj, "__call__") 'w przeciwnym razie powyższy kod powinien zadziałać. – jsbueno

+3

'callable()' zostało dodane z powrotem do języka w 3.2. –

+0

Myślę, że powinno być dobrze w Pythonie 3.2. Jak zauważają inni, w Pythonie 3.0 i 3.1 musisz zaimplementować 'callable', ale jeśli jesteś zadowolony z wersji 3.2, po prostu skopiuj, wklej i zapisz. –

Odpowiedz

6

Twoja implementacja compose jest ważna dla Pythona 3.2, jak opisano w komentarzach powyżej. Większość funkcji biblioteki, którą podałeś, ma odpowiednik w języku Python zapisany w documentation.

Funkcje takie jak map i filter są już zaimplementowane w Pythonie i mogą być po prostu wyrażone w postaci spisu. Python ma funkcję id zwracającą tożsamość obiektu (jako liczbę całkowitą), ale funkcja id biblioteki może być wyrażana jako lambda x: x.

Kolejne moduły można znaleźć interesujące są itertools i functools który ma partial i reduce (który jest podobny do foldl ale kolejność argument nie jest taka sama).

Oto proste implementacje kilku z nich, że nie znalazłem w bibliotece standardowej:

from functools import reduce 

def flip(f): 
    if not callable(f): 
     raise TypeError("Cannot filp a non-callable object") 
    def result(*args, **kw): 
     args = list(args) 
     args.reverse() 
     return f(*args, **kw) 
    return result 

def ilast(i): 
    return reduce(lambda _, x: x, i) 

def iscanl(f, v, seq): 
    yield v 
    for a in seq: 
     v = f(v, a) 
     yield v 

def scanl(*args, **kw): 
    return list(iscanl(*args, **kw)) 

def foldl(*args, **kw): 
    return ilast(iscanl(*args, **kw)) 
# Or using reduce 
#def foldl(f, v, seq): 
# return reduce(f, seq, v) 

def iscanr_reverse(f, v, seq): 
    return iscanl(flip(f), v, seq) 

def scanr(*args, **kw): 
    result = list(iscanr_reverse(*args, **kw)) 
    result.reverse() 
    return result 

def foldr(*args, **kw): 
    return ilast(iscanr_reverse(*args, **kw)) 
Powiązane problemy