¿Qué funcionalidad ofrece functools.partial que no se puede obtener a través de lambdas?
No hay mucho en términos de funcionalidad adicional (pero, véase más adelante) - y, facilidad de lectura está en el ojo del espectador.
La mayoría de las personas que están familiarizadas con los lenguajes de programación funcionales (las familias Lisp/Scheme en particular) parecen gustar lambda
bien - digo "más", definitivamente no todo, porque Guido y yo ciertamente estamos entre aquellos "familiarizado con" (etc.) aún piensa en lambda
como una anomalía de monstruosidad en Python ...
Estaba arrepentido de haberlo aceptado en Python mientras planeaba eliminarlo de Python 3, como uno de los "fallos técnicos de Python".
Lo apoyé completamente en eso. (Me encanta lambda
en el Esquema ... mientras que sus limitaciones en Python, y la forma extraña que no encaja en con el resto de la lengua, hacen que mi piel de gallina).
No es así, sin embargo, para las hordas de lambda
amantes - que llevaron a cabo una de las cosas más cercanas a una rebelión jamás visto en la historia de Python, hasta Guido dio marcha atrás y decidieron dejar lambda
en
Varias adiciones posibles a functools
. (para hacer funciones devolviendo constantes, identidad, etc.) no sucedió (para evitar duplicar explícitamente más de la funcionalidad de lambda
), aunque partial
por supuesto permaneció (no es total duplicación, ni es una monstruosidad).
Recuerde que el cuerpo de lambda
está limitado a expresión, por lo que tiene limitaciones. Por ejemplo...: Función
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
functools.partial
's volvieron está decorado con atributos útiles para la introspección - la función que ha de envolver, y lo posicionales y nombrados argumentos que fija en ella. Además, los argumentos con nombre se pueden anular la derecha de nuevo (la "fijación" es más bien, en un sentido, el ajuste de los valores predeterminados):
>>> f('23', base=10)
23
tanto, como se ve, es definely no tan simplista como lambda s: int(s, base=2)
! -)
Sí, usted podría retorcer su lambda para darle algo de esto - por ejemplo, para la palabra clave-predominante,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
pero muy caro espero que incluso la más ardiente lambda
-pluma no considera este horror más legible que la llamada partial
! -). La parte de "ajuste de atributo" es aún más difícil, debido a la limitación de "cuerpo es una sola expresión" de Python lambda
(más el hecho de que la asignación nunca puede ser parte de una expresión de Python) ... terminas "simulando asignaciones dentro de una expresión "estirando lista por comprensión mucho más allá de sus límites de diseño ...:
>>> f = [f for f in (lambda f: int(s, base=2),)
if setattr(f, 'keywords', {'base': 2}) is None][0]
Ahora combinar el overridability-argumentos con nombre, además de la configuración de tres atributos, en una sola expresión, y dime lo que puede leer va a ser ...! -)
Hm, en realidad soy de la creencia opuesta, me tomó mucho más tiempo analizar los 'functools '.llamada parcial, mientras que las lambdas son evidentes. –