Может кто-нибудь объяснить конкретные причины, по которым BDFL решили сделать лямбды Python однострочными?
Это хорошо:
lambda x: x**x
Это приводит к ошибке:
lambda x:
x**x
Я понимаю, что создание многострочного лямбда-выражения каким-то образом «нарушит» нормальные правила отступов и потребует добавления дополнительных исключений, но разве это не стоит преимуществ?
Посмотрите на JavaScript, например. Как можно жить без этих анонимных функций? Они незаменимы. Разве Pythonistas не хочет избавиться от необходимости называть каждую многострочную функцию просто для передачи ее в качестве аргумента?
def
? Теперь он имеет точно такую же визуальную структуру.Ответы:
Гидо ван ван Россум сам ответил на это:
http://www.artima.com/weblogs/viewpost.jsp?thread=147358
По сути, он говорит, что хотя решение возможно, оно не совпадает с тем, как работает Python.
источник
совершенно нормально делать многострочную лямбду в python: смотрите
настоящее ограничение лямбды заключается в том, что лямбда должна быть одним выражением ; он не может содержать ключевое слово (например, python2
print
илиreturn
).GvR выбирает это для ограничения размера лямбды, так как они обычно используются в качестве параметров. Если вы хотите настоящую функцию, используйте
def
источник
def
. Подумайте об этом: вам действительно нужен вызываемый элемент как параметр вашей функции? И пользователям этой функции не разрешено передавать ваш вызов по умолчанию? Как они могут передать это, если вы не даете это им?Я знаю, что это очень старый, но положить сюда в качестве ссылки.
Альтернативой использованию лямбды может быть использование
def
нестандартного способа. Цель состоит в том, чтобы передатьdef
функцию, которая может быть выполнена только при одном обстоятельстве - декоратор. Обратите внимание, что в этой реализацииdef result
не создается функция, она создает результатreduce()
, который в конечном итоге становитсяdict
.Бесстыдная вилка : я делаю много здесь .
Обратите внимание, что лямбда-выражения с несколькими утверждениями могут быть выполнены, но только с очень, очень уродливым кодом. Тем не менее, интересно то, как область видимости работает с этой реализацией (обратите внимание на многократное использование
name
переменной и ее затенениеmessage
.источник
Взлом вместе мульти-заявление лямбда не совсем так плохо , как pyrospade разбирает: что мы могли бы составить кучу монадических функций с помощью привязки, как в Haskell, но так как мы находимся в нечистом мире Python, мы могли бы также использовать побочные эффекты, чтобы достичь того же.
Я расскажу о нескольких способах сделать это в своем блоге .
Например, Python гарантирует, что элементы кортежа будут оцениваться по порядку, поэтому мы можем использовать их
,
как императив;
. Мы можем заменить много утверждений, напримерprint
, на выражения, какsys.stdout.write
.Следовательно, следующее эквивалентно:
Обратите внимание, что я добавил
None
в конце и извлек его с помощью[-1]
; это устанавливает возвращаемое значение явно. Нам не нужно этого делать, но без этого мы получили бы фанки(None, None, None)
возвращаемого значения, о котором мы можем заботиться или не заботиться.Таким образом, мы можем упорядочить действия ввода-вывода. Как насчет локальных переменных?
Python
=
формирует утверждение, поэтому нам нужно найти эквивалентное выражение. Одним из способов является изменение содержимого структуры данных, передаваемой в качестве аргумента. Например:Есть несколько трюков, которые используются в
stateful_lambda
:*_
Аргумент позволяет нашей лямбда принимать любое количество аргументов. Поскольку это допускает нулевые аргументы, мы восстанавливаем соглашение о вызовахstateful_def
._
- это просто соглашение, которое гласит: «Я не собираюсь использовать эту переменную»lambda state: lambda *_: ...
(lambda state: ...)({})
state
значению{}
без использования оператора присваивания (например,state = {}
)state
как имена переменных и связанные значенияstate.setdefault(a, b)
вместоa = b
иstate.get(a)
вместоa
[-1]
для извлечения последнего значения, которое действует какreturn
утверждениеКонечно, это довольно громоздко, но мы можем сделать более приятный API с помощью вспомогательных функций:
источник
Хотя я мог бы внести свой вклад, используйте прерыватель строки:
Не забывайте, что Python умеет писать на однослойных компьютерах, как в примере:
И лямбда очень мощная, но она не предназначена для замены одной целой функции, я имею в виду, что вы можете взломать ее так (пример заимствования у коллеги выше):
Но вы действительно хотите сделать это так? Через некоторое время он становится практически нечитаемым, это похоже на начало веревки, начиная с распутанного конца.
Лямбды представлены как единственные функции в карте, фильтруют и сокращают функции в функционально-ориентированном программировании (среди прочего). Например, получение символьных значений значений, которые являются целыми числами и делятся на 2
Вы можете использовать его как функцию выражения функции, определив сложную функцию (или несколько и более лямбда-выражений, и поместив ее в другую лямбду-выражение:
но в Python есть поддержка выражений функций по-другому: -lets говорят, что у вас есть вызванная функция,
superAwesomeFunction
и эта функция может делать какие-то суперские вещи, вы можете назначить ее переменной, не вызывая ее, например:Поэтому теперь, когда вы вызываете SAF, вы вызываете superAwesomeFunction или метод. Если вы выполните поиск в папке Lib, вы обнаружите, что большинство
__builtin__
модулей Python написаны именно так. Это сделано потому, что иногда вам понадобятся некоторые функции, которые выполняют определенную задачу, которая не является необходимой для использования пользователем, но необходима для нескольких функций. Итак, у вас есть выбор: вы не можете иметь 2 функции с именем «superAwesomeFunction», вы можете иметь «superAwesomeFunctionDoingBasicStuf» и «realSuperAwesomeFunction», а затем просто поместить «realSuperAwesomeFunction» в переменную «superAwesomeFunction», и все готово.Вы можете найти расположение импортированных модулей, введя в консоли
importedModule.__file__
(реальный примерimport os;os.__file__
), и просто следуйте по этому каталогу в файл с именем importModule.py, откройте его в редакторе и найдите, как вы можете максимизировать свои собственные «знания».Я надеюсь, что это поможет вам и другим коллегам, попавшим в беду.
источник