本文翻译自:No Multiline Lambda in Python: Why not?
I've heard it said that multiline lambdas can't be added in Python because they would clash syntactically with the other syntax constructs in Python. 我听说它说不能在Python中添加多行lambda,因为它们会在语法上与Python中的其他语法结构发生冲突。 I was thinking about this on the bus today and realized I couldn't think of a single Python construct that multiline lambdas clash with. 我今天在公共汽车上考虑这个问题,意识到我想不出一个与多行lambda冲突的Python结构。 Given that I know the language pretty well, this surprised me. 考虑到我非常了解该语言,这令我感到惊讶。
Now, I'm sure Guido had a reason for not including multiline lambdas in the language, but out of curiosity: what's a situation where including a multiline lambda would be ambiguous? 现在,我确定Guido有一个理由不在语言中包含多行lambda,而是出于好奇:在什么情况下包含多行lambda会导致歧义? Is what I've heard true, or is there some other reason that Python doesn't allow multiline lambdas? 我所听到的是对的,还是Python不允许多行lambda的其他原因?
#1楼
参考:https://stackoom.com/question/5aSk/Python中没有多行Lambda-为什么不呢
#2楼
Look at the following: 请看以下内容:
map(multilambda x:
y=x+1
return y
, [1,2,3])
Is this a lambda returning (y, [1,2,3])
(thus map only gets one parameter, resulting in an error)? 这是lambda返回(y, [1,2,3])
(因此映射仅获取一个参数,从而导致错误)吗? Or does it return y
? 还是返回y
? Or is it a syntax error, because the comma on the new line is misplaced? 还是语法错误,因为新行上的逗号放置不正确? How would Python know what you want? Python如何知道您想要什么?
Within the parens, indentation doesn't matter to python, so you can't unambiguously work with multilines. 在括号内,缩进对于python并不重要,因此您不能明确地使用多行。
This is just a simple one, there's probably more examples. 这只是一个简单的例子,可能还有更多示例。
#3楼
Guido van Rossum (the inventor of Python) answers this exact question himself in an old blog post . Guido van Rossum(Python的发明者)自己在一个旧博客文章中回答了这个确切的问题。
Basically, he admits that it's theoretically possible, but that any proposed solution would be un-Pythonic: 基本上,他承认这在理论上是可行的,但是任何建议的解决方案都是非Python的:
"But the complexity of any proposed solution for this puzzle is immense, to me: it requires the parser (or more precisely, the lexer) to be able to switch back and forth between indent-sensitive and indent-insensitive modes, keeping a stack of previous modes and indentation level. Technically that can all be solved (there's already a stack of indentation levels that could be generalized). But none of that takes away my gut feeling that it is all an elaborate Rube Goldberg contraption ." “但是,对于我来说,任何提议的解决方案的复杂性对我来说都是巨大的:它要求解析器(或更确切地说是词法分析器)能够在缩进敏感模式和缩进不敏感模式之间来回切换,并保持堆栈技术上可以解决所有问题(已经有可以概括的缩进级别堆栈了。)但是,这些都不让我直觉,这完全是精心制作的Rube Goldberg装置 。”
#4楼
A couple of relevant links: 一些相关链接:
For a while, I was following the development of Reia, which was initially going to have Python's indentation based syntax with Ruby blocks too, all on top of Erlang. 一段时间以来,我一直在关注Reia的开发,该开发最初也将基于Python的基于缩进的语法以及Ruby块(全部基于Erlang)。 But, the designer wound up giving up on indentation sensitivity, and this post he wrote about that decision includes a discussion about problems he ran into with indentation + multi-line blocks, and an increased appreciation he gained for Guido's design issues/decisions: 但是,设计师最终放弃了缩进敏感性,他写的有关该决定的文章包括有关他在缩进+多行块中遇到的问题的讨论,以及他对Guido的设计问题/决定的越来越多的赞赏:
http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html http://www.unlimitednovelty.com/2009/03/indentation-sensitiveivity-post-mortem.html
Also, here's an interesting proposal for Ruby-style blocks in Python I ran across where Guido posts a response w/o actually shooting it down (not sure whether there has been any subsequent shoot down, though): 另外,这是关于Python中Ruby样式块的一个有趣的建议,我遇到了Guido在哪里发布了一个响应,但没有将其实际击落(尽管不确定是否有任何后续击落):
http://tav.espians.com/ruby-style-blocks-in-python.html http://tav.espians.com/ruby-style-blocks-in-python.html
#5楼
This is generally very ugly (but sometimes the alternatives are even more ugly), so a workaround is to make a braces expression: 通常这很丑陋(但有时替代方法甚至更丑陋),因此一种解决方法是制作一个大括号表达式:
lambda: (
doFoo('abc'),
doBar(123),
doBaz())
It won't accept any assignments though, so you'll have to prepare data beforehand. 不过,它不会接受任何分配,因此您必须事先准备数据。 The place I found this useful is the PySide wrapper, where you sometimes have short callbacks. 我发现这个有用的地方是PySide包装器,有时在其中有简短的回调。 Writing additional member functions would be even more ugly. 编写其他成员函数将更加难看。 Normally you won't need this. 通常,您不需要这个。
Example: 例:
pushButtonShowDialog.clicked.connect(
lambda: (
field1.clear(),
spinBox1.setValue(0),
diag.show())
#6楼
Let me try to tackle @balpha parsing problem. 让我尝试解决@balpha解析问题。 I would use parentheses around the multiline lamda. 我会在多行lamda周围使用括号。 If there is no parentheses, the lambda definition is greedy. 如果没有括号,则lambda定义为贪婪的。 So the lambda in 所以lambda在
map(lambda x:
y = x+1
z = x-1
y*z,
[1,2,3]))
returns a function that returns (y*z, [1,2,3])
返回返回(y*z, [1,2,3])
的函数
But 但
map((lambda x:
y = x+1
z = x-1
y*z)
,[1,2,3]))
means 手段
map(func, [1,2,3])
where func is the multiline lambda that return y*z. 其中func是返回y * z的多行lambda。 Does that work? 那样有用吗?