¿Qué funcionalidad functools.partial
ofrece 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 lambda
bien: digo "la mayoría", definitivamente no todas, porque Guido y yo seguramente estamos entre los "familiarizados" (etc. ) Sin embargo, piensa que lambda
es 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 lambda
amantes, 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 lambda
funcionalidades), aunque partial
por supuesto permaneció (no es una duplicación total , ni es una monstruosidad).
Recuerde que lambda
el 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.partial
La 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 lambda
amante más ardiente no considere este horror más legible que la partial
llamada! -). 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.partial
que 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
?