Quelle fonctionnalité functools.partial
offre que vous ne pouvez pas obtenir avec lambdas?
Pas beaucoup en termes de fonctionnalités supplémentaires (mais, voir plus loin) - et la lisibilité est dans l'œil du spectateur.
La plupart des gens qui connaissent les langages de programmation fonctionnels (ceux des familles Lisp / Scheme en particulier) semblent aimer lambda
très bien - je dis "la plupart", certainement pas tous, parce que Guido et moi sommes assurément parmi ceux qui "sont familiers" (etc.) ) mais pense lambda
à une anomalie horrible en Python ...
Il se repentait de ne jamais l'avoir acceptée en Python alors qu'il prévoyait de le supprimer de Python 3, comme l'un des "pépins de Python".
Je l'ai pleinement soutenu à cet égard. (J'adore lambda
dans Scheme ... tandis que ses limitations en Python , et la façon étrange qu'il ne fait pas avec le reste du langage, font ramper ma peau).
Ce n'est pas le cas, cependant, pour les hordes d' lambda
amoureux - qui ont organisé l'une des choses les plus proches d'une rébellion jamais vue dans l'histoire de Python, jusqu'à ce que Guido revienne en arrière et décide de partir lambda
.
Plusieurs ajouts possibles à functools
(pour rendre les fonctions renvoyant des constantes, l'identité, etc) ne s'est pas produit (pour éviter de dupliquer explicitement plus de lambda
fonctionnalités), bien partial
qu'il soit bien sûr resté (ce n'est pas une duplication totale , ni une horreur).
N'oubliez pas que lambda
le corps est limité à être une expression , il a donc des limites. Par exemple...:
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
functools.partial
La fonction renvoyée est décorée d'attributs utiles pour l'introspection - la fonction qu'elle encapsule et les arguments positionnels et nommés qu'elle y corrige. De plus, les arguments nommés peuvent être remplacés tout de suite (la «correction» est plutôt, dans un sens, la définition des valeurs par défaut):
>>> f('23', base=10)
23
Donc, comme vous le voyez, ce n'est certainement pas aussi simpliste que lambda s: int(s, base=2)
! -)
Oui, vous pouvez déformer votre lambda pour vous en fournir une partie - par exemple, pour le mot clé prioritaire,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
mais j'espèrelambda
sincèrement que même l' amant le plus ardent ne considère pas cette horreur plus lisible que l' partial
appel! -). La partie "définition d'attribut" est encore plus difficile, en raison de la limitation "corps une seule expression" de Python lambda
(plus le fait que l'affectation ne peut jamais faire partie d'une expression Python) ... vous finissez par "simuler des affectations dans une expression" en étirant la compréhension de la liste bien au-delà de ses limites de conception ...:
>>> f = [f for f in (lambda f: int(s, base=2),)
if setattr(f, 'keywords', {'base': 2}) is None][0]
Maintenant, combinez la substituabilité des arguments nommés, plus le réglage de trois attributs, en une seule expression, et dites-moi à quel point cela sera lisible ...!
functools.partial
que vous avez mentionnée la rend supérieure à lambda. C'est peut-être le sujet d'un autre article, mais qu'est-ce qui vous dérange tant au niveau du designlambda
?