【发布时间】:2018-10-09 23:30:35
【问题描述】:
这不是 Assignment inside lambda expression in 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。但这听起来很蹩脚而且会 易于修复(一种方法:使 lambda 表达式返回Noneif body 是一个语句)。
不是答案:
因为它是这样定义的(我想知道为什么它是这样定义的)。
因为它在语法中(见上文)。
如果需要语句,请使用
def(我没有问如何获取 语句到函数中)。
“这会改变语法/语言/语义”如果你能想出一个这样的改变的例子,以及为什么它会不好的话,作为答案是可以的。
【问题讨论】:
-
因为
lambdas故意仅限于表达式。如果您想要所有其他内容,只需使用完整的函数定义。这是规格:docs.python.org/3/reference/expressions.html#lambda -
将赋值设为语句而不是表达式的理由是,像
if x = 3:(而不是if x == 3:)这样的拼写错误会变成语法错误,而不是细微的运行时语义错误。 -
您的特定示例存在漏洞:
lambda x: setattr(c, 'v', 99)。 -
以上 cmets 都对这个问题没有用处。有些人甚至可能没有完全阅读我的问题。
标签: python lambda python-internals side-effects