2010-07-01 2 views
1

В приведенном ниже коде я намереваюсь иметь две кнопки, а при каждом нажатии «0» и «1» должны быть напечатаны соответственно на stdout. Однако, когда программа запускается, они оба печатают «1», что является последним значением, которое у меня было для итерации. Зачем?лямбда-итерация Python не работает по назначению

import Tkinter as tk 
import sys 

root = tk.Tk() 

for i in range(0,2): 
    cmd = lambda: sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'" % i,command=cmd).pack() 

root.mainloop() 

ответ

5

The i не улавливается в лямбда при ее создании (как вы хотите). Вместо этого обе функции ссылаются на i во внешнем цикле, который изменяется после создания функции и перед ее запуском. Для того, чтобы захватить его, вы можете использовать значение по умолчанию:

for i in range(0,2): 
    cmd = lambda i=i: sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'" % i,command=cmd).pack() 
3

Конечно, это вопрос в

On lambdas, capture, and mutability

, который появляется снова и снова ...

+0

, что статья не имеет отношения к питона – newacct

+1

Он имеет ссылки на две подобные вопросы StackOverflow в Python, и этот вопрос выходит за рамки большинства языков с лямбда и mutables. – Brian

1

Я думаю, что это немного странно использовать анонимную функцию, чтобы затем дать ей имя. Почему бы не написать так?

for i in 0,1: 
    def cmd(): 
     return sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'"%i, command=cmd).pack() 
+1

@newacct: «for i in 0,1» - правильный синтаксис. Попробуйте в интерактивной оболочке Python и посмотрите, что произойдет. – Deestan

 Смежные вопросы

  • Нет связанных вопросов^_^