13

Python 3.2 documentation riferisce a Collin Winter's functional module contenente funzione compose:funzione di composizione e modulo funzionale

La composizione() funzione implementa composizione di funzioni. In altre parole , restituisce un wrapper attorno alle callebles esterne e interne, ad esempio che il valore di ritorno dall'interno viene alimentato direttamente all'esterno.

Sfortunatamente, questo modulo non è stato aggiornato da luglio 2006; Mi chiedo se c'è qualche sostituzione disponibile.

Per ora, ho solo bisogno della funzione compose. La seguente definizione originale di functional.compose è ancora valida per Python 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 

Questo SO question è in qualche modo correlato; chiede se Python debba supportare la sintassi speciale per compose.

+0

Python 3 fa ot hanno la 'callable' costruita nel parola chiave - di solito è sostituito con' hasattr (obj, "__call__") 'altrimenti, il codice sopra dovrebbe funzionare. – jsbueno

+3

'callable()' è stato aggiunto alla lingua in 3.2. –

+0

Penso che dovrebbe andare bene in Python 3.2. Come altri sottolineano, per Python 3.0 e 3.1, è necessario implementare 'callable', ma se si è soddisfatti di 3.2, basta copiare, incollare e accreditare. –

risposta

6

L'implementazione di compose è valida per python 3.2 come discusso nei commenti sopra. La maggior parte delle funzioni della libreria che hai fornito hanno un equivalente python scritto nello documentation.

Funzioni come map e filter sono già implementate in python e possono anche essere semplicemente espresse come list comprehensions. Python ha una funzione id che restituisce l'identità di un oggetto (come numero intero), ma la funzione id della libreria può essere espressa come lambda x: x.

Altri moduli si potrebbe trovare interessanti sono itertools e functools che ha partial e reduce (che è simile a foldl ma l'ordine degli argomenti non è la stessa).

Ecco un semplice implementazioni di alcuni di loro che non ho nella libreria standard troviamo:

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