Quale funzionalità functools.partial
offre che non è possibile superare lambdas?
Non molto in termini di funzionalità extra (ma, vedi più avanti) - e la leggibilità è negli occhi di chi guarda.
La maggior parte delle persone che hanno familiarità con i linguaggi di programmazione funzionale (in particolare quelli delle famiglie Lisp / Scheme) sembrano lambda
proprio bene - dico "la maggior parte", sicuramente non tutti, perché Guido ed io siamo sicuramente tra quelli "familiari" (ecc. ) eppure lambda
considera un'anomalia del pugno nell'occhio in Python ...
Si pentì di non averlo mai accettato in Python mentre aveva pianificato di rimuoverlo da Python 3, come uno dei "difetti di Python".
L'ho pienamente supportato in questo. (Adoro lambda
in Scheme ... mentre i suoi limiti in Python e il modo strano in cui non funziona con il resto della lingua, strisciare la pelle).
Non è così, tuttavia, per le orde di lambda
innamorati, che hanno messo in scena una delle cose più vicine a una ribellione mai vista nella storia di Python, fino a quando Guido non ha fatto un passo indietro e ha deciso di abbandonare lambda
.
Diverse possibili aggiunte a functools
(per rendere le funzioni che restituiscono costanti, identità, ecc.) non è accaduto (per evitare di duplicare esplicitamente più lambda
funzionalità), anche se partial
ovviamente è rimasto (non è una duplicazione totale , né è un pugno nell'occhio).
Ricorda che lambda
il corpo è limitato per essere un'espressione , quindi ha dei limiti. Per esempio...:
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
functools.partial
La funzione restituita è decorata con attributi utili per l'introspezione - la funzione che sta avvolgendo, e quali argomenti posizionali e nominati correggono in essa. Inoltre, gli argomenti nominati possono essere sovrascritti (il "fissaggio" è piuttosto, in un certo senso, l'impostazione delle impostazioni predefinite):
>>> f('23', base=10)
23
Quindi, come vedi, non è sicuramente così semplice lambda s: int(s, base=2)
! -)
Sì, si potrebbe contorcere il tuo lambda per darvi alcune di queste - ad esempio, per la parola chiave-override,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
ma spero vivamente che anche il più ardente lambda
amante non consideri questo orrore più leggibile della partial
chiamata! -). La parte "impostazione dell'attributo" è ancora più difficile, a causa del limite "Python di una singola espressione" lambda
(oltre al fatto che l'assegnazione non può mai far parte di un'espressione Python) ... si finisce per "falsificare le assegnazioni all'interno di un'espressione" allungando la comprensione della lista ben oltre i suoi limiti di progettazione ...:
>>> f = [f for f in (lambda f: int(s, base=2),)
if setattr(f, 'keywords', {'base': 2}) is None][0]
Ora unire l'overridability-argomenti con nome, oltre alla cornice di tre attributi, in una singola espressione, e mi dica quanto sia leggibile , che sta per essere ...!
functools.partial
cui hai parlato la rende superiore a lambda. Forse questo è l'argomento di un altro post, ma cos'è a livello di design che ti preoccupa così tantolambda
?