<p>当python执行一个函数时,它会创建一个命名空间来保存局部变量。lambda在里面</p>
<pre><code>button.clicked.connect(lambda: self.squareButtonHandler(buttonNumber))
</code></pre>
<p>是一个内部函数,它在外部作用域中包含对<code>buttonNumber</code>的引用。当您将lambda传递给<code>button.clicked.connect</code>时,python必须以某种方式记住该引用。它通过将外部作用域的上下文添加到它创建并传递给<code>connect</code>的函数对象来实现这一点。您连接的所有按钮的函数对象引用相同的外部上下文,这意味着当函数退出时,它们都将看到<code>buttonNumber</code>中的内容。在</p>
<p>下面是一个正在运行的示例,它显示了您的问题</p>
^{pr2}$
<p>它产生了</p>
<pre><code>test 1
button 4
button 4
button 4
button 4
button 4
</code></pre>
<p>是的,这就是问题所在。让我们看看通过查看函数对象的闭包创建的函数对象</p>
<pre><code>print("test 2")
for handler in try_lambda():
handler()
print(handler, handler.__closure__)
</code></pre>
<p>它显示了</p>
<pre><code>test 2
button 4
<function try_lambda.<locals>.<lambda> at 0x7f66e34a9d08> (<cell at 0x7f66e49fb3a8: int object at 0xa68aa0>,)
button 4
<function try_lambda.<locals>.<lambda> at 0x7f66e34a9d90> (<cell at 0x7f66e49fb3a8: int object at 0xa68aa0>,)
button 4
<function try_lambda.<locals>.<lambda> at 0x7f66e34a9e18> (<cell at 0x7f66e49fb3a8: int object at 0xa68aa0>,)
button 4
<function try_lambda.<locals>.<lambda> at 0x7f66e34a9ea0> (<cell at 0x7f66e49fb3a8: int object at 0xa68aa0>,)
button 4
<function try_lambda.<locals>.<lambda> at 0x7f66e349a048> (<cell at 0x7f66e49fb3a8: int object at 0xa68aa0>,)
</code></pre>
<p>有趣。我们有4个不同的函数对象(0x7f66e34a9d08,等等),但是只有一个单元格保存我们想要的变量0x7f66e49fb3a8。这就是为什么它们都看到相同的数字-它们都使用外部函数的局部变量中保存的相同单元格。在</p>
<p>{cd5>在这种情况下,{cd5}是更好的选择。它使用一个变量的<em>当前</em>值创建一个函数,并按照您想要的方式工作。在</p>
<pre><code>import functools
def try_partial():
handlers = []
for num in range(5):
handlers.append(functools.partial(buttonHandler, num))
return handlers
print("test 3")
for handler in try_partial():
handler()
</code></pre>
<p>它产生了</p>
<pre><code>test 3
button 0
button 1
button 2
button 3
button 4
</code></pre>