SORU
2 HAZİRAN 2009, Salı


Python lambda fonksiyonlar ve parametreler kapsamında

Neredeyse tam gui bir dizi etkinlik için aynı olan bir geri çağırma işlevi ihtiyacım var. İşlevi biraz farklı adı olan göre davranacaktır. Bana basit bir dava gibi görünüyor, ama lambda fonksiyonları bu garip davranış, çözemedim bir türlü.

Aşağıdaki basitleştirilmiş aşağıdaki kodu var:

def callback(msg):
    print msg

#creating a list of function handles with an iterator
funcList=[]
for m in ('do', 're', 'mi'):
    funcList.append(lambda: callback(m))
for f in funcList:
    f()

#create one at a time
funcList=[]
funcList.append(lambda: callback('do'))
funcList.append(lambda: callback('re'))
funcList.append(lambda: callback('mi'))
for f in funcList:
    f()

Bu kodun çıktısı:

    mi
    mi
    mi
    do
    re
    mi

Beklediğim:

    do
    re
    mi
    do
    re
    mi

Neden bir yineleyici kötü şeyler kullanan var mı?

Bir deepcopy kullanarak denedim:

import copy
funcList=[]
for m in ('do', 're', 'mi'):
    funcList.append(lambda: callback(copy.deepcopy(m)))
for f in funcList:
    f()

Ama bu aynı sorun var. Bana python daha iyi anlamamıza yardımcı olduğunuz için teşekkürler! Bu seni anlamama yardım et sonra bir anlam ifade edecektir eminim! :)

CEVAP
2 HAZİRAN 2009, Salı


Lambda oluşturulduğunda, kullandığı kapsayan kapsamında değişkenleri bir kopyasını yapmaz. Değişken değeri daha sonra bakmak böylece çevreye bir referans tutar. 7* *sadece bir tane var. Döngü her zaman için atanır. Döngü sonra, 8* *değişken değeri 'mi' vardır. Aslında daha sonra oluşturduğunuz fonksiyon çalıştırıldığında, o zamana kadar değeri olan, onu yaratan ortamda m değerini arayın. 'mi'.

Bu soruna ortak bir çözüm; isteğe bağlı parametre varsayılan argüman olarak kullanarak lambda oluşturduğunuz anda m değeri yakalamak. Sen kod değiştirmek zorunda değilsin bu yüzden genellikle aynı adı taşıyan bir parametre kullanın:

for m in ('do', 're', 'mi'):
    funcList.append(lambda m=m: callback(m))

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jonathan D.

    Jonathan D.

    3 Kasım 2006
  • Marissah Simonini

    Marissah Sim

    25 HAZİRAN 2013
  • MrOctopi

    MrOctopi

    6 Aralık 2010