Это не дубликат Assignment внутри лямбда-выражения в Python, т. е. я я не спрашиваю, как заставить Python присваивать значения в выражении lambda
.
У меня есть некоторый опыт λ-исчисления. Учитывая следующий код, похоже, что Python вполне готов выполнять побочные эффекты в выражениях lambda
:
#!/usr/bin/python
def applyTo42(f):
return f(42)
def double(x):
return x * 2
class ContainsVal:
def __init__(self, v):
self.v = v
def store(self, v):
self.v = v
def main():
print('== functional, no side effects')
print('-- print the double of 42')
print(applyTo42(double))
print('-- print 1000 more than 42')
print(applyTo42(lambda x: x + 1000))
print('-- print c\'s value instead of 42')
c = ContainsVal(23)
print(applyTo42(lambda x: c.v))
print('== not functional, side effects')
print('-- perform IO on 42')
applyTo42(lambda x: print(x))
print('-- set c\'s value to 42')
print(c.v)
applyTo42(lambda x: c.store(x))
print(c.v)
#print('== illegal, but why?')
#print(applyTo42(lambda x: c.v = 99))
if __name__ == '__main__':
main()
Но если я раскомментирую строки
print('== illegal, but why?')
print(applyTo42(lambda x: c.v = 99))
Я получу
SyntaxError: lambda cannot contain assignment
Почему бы нет? Какова более глубокая причина этого?
Как показывает код, речь не может идти о «чистоте» в функциональном смысле.
Единственное объяснение, которое я могу себе представить, это то, что assignemts ничего не возвращают, даже
None
. Но это звучит неубедительно, и это было бы легко исправить (один из способов: заставить лямбда-выражения возвращатьNone
, если тело является оператором).
Не ответ:
Потому что он так определен (я хочу знать, почему он так определен).
Потому что это в грамматике (см. выше).
Используйте
def
, если вам нужны операторы (я не спрашивал, как получить операторы в функцию).
«Это изменит синтаксис/язык/семантику» подойдет в качестве ответа, если вы можете привести пример такого изменения и почему это будет плохо.
lambdas
преднамеренно ограничены только выражениями. Если вам нужны все остальные, просто используйте полное определение функции. Вот спецификация: docs.python.org/3/reference/expressions.html. #лямбда - person juanpa.arrivillaga   schedule 29.04.2018if x = 3:
(вместоif x == 3:
), становится синтаксической ошибкой, а не тонкой семантической ошибкой времени выполнения. - person chepner   schedule 29.04.2018lambda x: setattr(c, 'v', 99)
. - person chepner   schedule 29.04.2018def
, и фактически представляют собой удобство, которое было почти полностью исключено из языка во время разработки Python 3. - person chepner   schedule 29.04.2018