Какую функциональность предлагает functools.partial, которую нельзя получить через лямбды?
Не так много с точки зрения дополнительной функциональности (но об этом позже)- и читаемость - в глазах смотрящего.
Большинству людей, знакомых с функциональными языками программирования (в частности, в семьях Lisp / Scheme), кажется, lambda
нравится просто отлично - я говорю «большинство»"определенно не все, потому что мы с Гвидо, несомненно, являемся одними из тех, кто" знаком с "(и т. д.), но все же думают о lambda
как аномалии от глазной боли в Python ...
Он был раскаявшимся когда-либоприняв его в Python, в то время как планировал удалить его из Python 3, как один из «глюков Python».
Я полностью поддержал его в этом.(Я люблю lambda
в Схеме ... в то время как его ограничения в Python , и странный способ, которым он просто не вписывается в с остальнымиязык, заставь мою кожу ползти).
Однако это не так для полчищ любовников lambda
, которые устроили одну из самых близких вещей к восстанию, когда-либо встречавшемуся в истории Python, пока Гвидо не отступил ирешил оставить lambda
in.
Несколько возможных дополнений к functools
(чтобы сделать функции, возвращающие константы, идентичность и т. д.) не произошло (чтобы избежать явного дублирования большей части функциональности lambda
), хотя partial
конечно же осталось (это не всего дублирования, и при этом это не больно).
Помните, что тело lambda
ограничено выражением , так что у него есть ограничения.Например ...:
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
* Возвращенная функция 1039 * украшена атрибутами, полезными для самоанализа - функцией, которую она оборачивает, и позиционными и именованными аргументами, которые она там исправляет.Кроме того, именованные аргументы могут быть переопределены сразу назад («исправление» - это, скорее, установка значений по умолчанию):
>>> f('23', base=10)
23
Итак, как вы видите, это определенно не так просто, как lambda s: int(s, base=2)
! -)
Да, вы могли бы исказить лямбду, чтобы дать вам что-то из этого - например, для переопределения ключевых слов,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
но я очень надеюсь , что даже самый пылкий lambda
любитель не считает этот ужас более читабельным, чем вызов partial
! -).Часть «установки атрибутов» еще сложнее, из-за ограничения «тело в одном выражении» в lambda
Python (плюс тот факт, что присваивание никогда не может быть частью выражения Python) ... вы в конечном итоге «поддельные присвоения в пределахвыражение ", растягивая понимание списка далеко за пределы его дизайна ...:
>>> f = [f for f in (lambda f: int(s, base=2),)
if setattr(f, 'keywords', {'base': 2}) is None][0]
Теперь объедините переопределяемость именованных аргументов, плюс настройку трех атрибутов, в одно выражение, и расскажите мне, как для чтения будет ...! -)