Quelle fonctionnalité functools.partialoffre 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 lambdatrè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' lambdaamoureux - 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 lambdafonctionnalités), bien partialqu'il soit bien sûr resté (ce n'est pas une duplication totale , ni une horreur).
N'oubliez pas que lambdale 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.partialLa 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' partialappel! -). 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.partialque 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?