SORU
14 EYLÜL 2012, Cuma


Python iç içe fonksiyonlar yerel değişkenler

Tamam, bu konuda bana sabret görünecek biliyorum korkunç kıvrık, ama lütfen bana neler olduğunu anlamanıza yardımcı olur.

from functools import partial

class Cage(object):
    def __init__(self, animal):
        self.animal = animal

def gotimes(do_the_petting):
    do_the_petting()

def get_petters():
    for animal in ['cow', 'dog', 'cat']:
        cage = Cage(animal)

        def pet_function():
            print "Mary pets the "   cage.animal   "."

        yield (animal, partial(gotimes, pet_function))

funs = list(get_petters())

for name, f in funs:
    print name   ":", 
    f()

Verir:

cow: Mary pets the cat.
dog: Mary pets the cat.
cat: Mary pets the cat.

Yani temelde, neden üç farklı hayvan almıyorum? cage 'paketlenmiş' iç içe işlev yerel bir kapsam içinde değil mi? Nasıl iç içe geçmiş işlev çağrısı yerel değişkenler aramaz?

Bu tür bir sorun haline çalışan genellikle bir anlamı olduğunu biliyorum yanlış yapıyorum ama ne olduğunu anlamak istiyorum.

CEVAP
14 EYLÜL 2012, Cuma


İç içe fonksiyon tanımlı değil, yürütülen, üst kapsam değişkenleri arar.

Bu işlev gövdesi derlenmiş, ve 'özgür' değişkenleri (tanımlı fonksiyonu atama), doğrulanmış, daha sonra bağlı olarak kapatılması hücre fonksiyonu ile kod kullanarak bir dizin için başvuru her bir hücre. pet_function böylece vardırbirsonra kapanması bir hücre üzerinden başvurulan serbest değişken (cage), 0 dizin. Kapağın kendisini get_petters fonksiyon içinde yerel değişken cage puan.

Aslında işlevini çağırdığınızda, bu kapatma daha sonra çevredeki kapsamında cage değerini bakmak için kullanılıranda işlevini çağırın. Burada sorun yatıyor. Fonksiyonları dediğiniz zaman, get_petters işlevi zaten bu sonuçlar bilgi işlem yapılır. cage yerel değişken bir noktada sırasında yürütme tahsisli her 'cow', 'dog' 'cat' dizeler, ama sonunda işlevi, cage içeren son değeri 'cat'. Dinamik olarak döndürülen fonksiyonlar her aradığınızda böylece, değeri olsun 'cat' basılmış.

Bu kilitler güvenmek değil-geçici bir çözüm. Bir kullanabilirsinizkısmi fonksiyonbunun yerine, bir oluşturyeni scope fonksiyonuya da bir değişkeni bağlamakanahtar kelime parametre için varsayılan değer.

  • Kısmi fonksiyon örneği, functools.partial() kullanarak:

    from functools import partial
    
    def pet_function(cage=None):
        print "Mary pets the "   cage.animal   "."
    
    yield (animal, partial(gotimes, partial(pet_function, cage=cage)))
    
  • Yeni bir kapsam örnek oluşturma:

    def scoped_cage(cage=None):
        def pet_function():
            print "Mary pets the "   cage.animal   "."
        return pet_function
    
    yield (animal, partial(gotimes, scoped_cage(cage)))
    
  • Anahtar kelime parametre için varsayılan değer olarak değişken etmektedir

    def pet_function(cage=cage):
        print "Mary pets the "   cage.animal   "."
    
    yield (animal, partial(gotimes, pet_function))
    

Döngü pet_function scoped_cage fonksiyon tanımlamaya gerek yok, derleme sadece bir kez gerçekleşir, her döngüye yineleme üzerinde değil.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Fuse

    Fuse

    21 Kasım 2005
  • HTC

    HTC

    12 Ocak 2006
  • SignatureSeries

    SignatureSer

    24 Aralık 2006