¿Qué funcionalidad functools.partialofrece que no puedes obtener a través de lambdas?
No mucho en términos de funcionalidad adicional (pero, ver más adelante), y la legibilidad está en el ojo del espectador.
Parece que a la mayoría de las personas que están familiarizadas con los lenguajes de programación funcionales (en particular las de las familias Lisp / Scheme) les gusta lambdabien: digo "la mayoría", definitivamente no todas, porque Guido y yo seguramente estamos entre los "familiarizados" (etc. ) Sin embargo, piensa que lambdaes una anomalía monstruosa en Python ...
Se arrepintió de haberlo aceptado en Python, mientras que planeaba eliminarlo de Python 3, como uno de los "problemas técnicos de Python".
Lo apoyé completamente en eso. (Me encanta lambda en Scheme ... mientras que sus limitaciones en Python , y la forma extraña en que simplemente no con el resto del lenguaje, haz que mi piel se arrastre).
Sin embargo, no es así para las hordas de lambdaamantes, que organizaron una de las cosas más cercanas a una rebelión jamás vista en la historia de Python, hasta que Guido retrocedió y decidió irse lambda.
Varias adiciones posibles a functools(para hacer que las funciones regresen constantes, identidad, etc) no sucedió (para evitar duplicar explícitamente más lambdafuncionalidades), aunque partialpor supuesto permaneció (no es una duplicación total , ni es una monstruosidad).
Recuerde que lambdael cuerpo está limitado a ser una expresión , por lo que tiene limitaciones. Por ejemplo...:
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
functools.partialLa función devuelta está decorada con atributos útiles para la introspección: la función que está ajustando y qué argumentos posicionales y nombrados fija allí. Además, los argumentos nombrados pueden anularse de inmediato (la "fijación" es, en cierto sentido, la configuración de los valores predeterminados):
>>> f('23', base=10)
23
Entonces, como ves, ¡ definitivamente no es tan simplista como lambda s: int(s, base=2)! -)
Sí, podría contorsionar su lambda para darle algo de esto, por ejemplo, para la anulación de palabras clave,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
¡Pero espero que incluso el lambdaamante más ardiente no considere este horror más legible que la partialllamada! -). La parte de "configuración de atributos" es aún más difícil, debido a la limitación de "cuerpo de 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 "falsificando tareas dentro de una expresión" estirando la comprensión de la lista 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 combine la sobreescritura de argumentos nombrados, más la configuración de tres atributos, en una sola expresión, y dígame cuán legible será eso ...!
functools.partialque mencionaste lo hace superior a lambda. Tal vez este es el tema de otra publicación, pero ¿qué es lo que te molesta tanto a nivel de diseñolambda?