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

  • BigBoyTV

    BigBoyTV

    25 EYLÜL 2013
  • BioHunta

    BioHunta

    28 Mayıs 2006
  • UnboxTechnology

    UnboxTechnol

    20 Ocak 2011