2012-06-02 27 views
18

Bir for döngüsü içinde titreme içinde düğmeler oluşturmaya çalışıyorum. Ve her döngüde i sayım değerini komut değerinde bir argüman olarak geçirir. Böylece, işlev komut değerinden çağrıldığında, hangi tuşa basıldığını söyleyebilirim ve buna göre hareket etmeliyim. Sorun, len 3 olduğunu söyler, "Oyun 3" ile "Oyun 1" başlıklı 3 düğme oluşturacak, ancak düğmelerden herhangi birine basıldığında, yazdırılan değer her zaman 2, son yinelemedir. Bu yüzden düğmeler ayrı varlıklar olarak yapılmış gibi görünüyor, ancak komut argümanlarındaki i değeri hepsi aynı görünüyor.Python trankter'i, döngü bağımsız değişkenleri iletmek için

def createGameURLs(self): 
    self.button = [] 
    for i in range(3): 
     self.button.append(Button(self, text='Game '+str(i+1),command=lambda:self.open_this(i))) 
     self.button[i].grid(column=4, row=i+1, sticky=W) 
def open_this(self, myNum): 
    print(myNum) 

akım i değerini almanın bir yolu var mı bu özel düğmesi ile sopa, her yineleme üzerine: İşte kod nedir? Şimdiden teşekkür ederim.

+0

İkinize de teşekkürler LukaD ve BrenBarn, birkaç gün boyunca bununla savaşıyorum, inanıyorum ya da etmeyin. Her iki yol da mükemmel çalıştı. Şu an için gittim, şu an için düzeltiyorum, ama kesinlikle functools'u okuyacağım. Her iki cevabı da takdir ediyorum. – Marcel

+0

BrenBarns çözümü sizin için çalışıyorsa, kabul ettiğiniz yanıt olarak işaretlemelisiniz. – lukad

+0

[python Tkinter düğmesi komutunda argümanı geçerek] olası bir kopyası (http://stackoverflow.com/questions/6920302/passing-argument-in-python-tkinter-button-command) –

cevap

6

Python'da bu nasıl çalışır. Bu soruna kendim bir kez girdim. Bunun için functools.partial kullanabilirsiniz.

for i in range(3): 
    self.button.append(Button(self, text='Game '+str(i+1), command=partial(self.open_this, i))) 
34
lambda i=i: self.open_this(i) için lambda değiştirin

.

Bu büyülü görünebilir, ancak burada neler oluyor. Fonksiyonunuzu tanımlamak için bu lambda'yı kullandığınızda, open_this çağrısı fonksiyonu tanımladığınız sırada i değişkeninin değerini alamaz. Bunun yerine, " olarak adlandırdığım anda" değişkeninin değerine bakmalıyım "diyen bir not gibi bir kapanış yapar. Elbette, döngü bittikten sonra işlev çağrılır, böylece o zaman daima döngüden son değere eşit olurum.

i=i trick'in kullanılması, işlevinizin, i'nin geçerli değerini, lambda'nızın tanımlandığı zamanda, daha sonra değerine bakmayı beklemek yerine saklamasına neden olur.

+0

Eğer iki argümana geçmek istediysek open_this gibi bir işlev? – Amen

+1

@Amen: Bu argümanların ne olmasını istediğinize bağlı. Eğer her ikisi de bir dış döngüden geliyorsa ve her ikisini de yukarıda gösterildiği gibi "dondurmak" istiyorsanız, sadece lambda x = x, y = y: self.open_this (x, y) 'yaparsınız. – BrenBarn

+0

Bu, parlak, anlaşılır ve iyi bir açıklamadır. Cevap bu olmalı. – Battleroid

İlgili konular