2011-12-17 21 views
12

Peter Norvig'in web sitesinden aşağıdaki kod snippet'ini aldım; fonksiyon çağrılarındaki hafızayı etkinleştirmek için bir dekoratördür (basit bir dinamik programa bir üstel yinelemeyi değiştirmek için önceki çağrıları önbelleğe alma).Bu python işlevinde neden bir çizgi gerekli? (memoized recursion)

def memo(f): 
    table = {} 
    def fmemo(*args): 
     if args not in table: 
      table[args] = f(*args) 
     return table[args] 
    fmemo.memo = table 
    return fmemo 

Bu kod düzgün çalışıyor, ancak ikinci satırın neden gerekli olduğunu merak ediyorum. Bu, Python hakkındaki bilgimdeki bir boşluktur, fakat çizgiyi kaldırmak ve basit bir fibonacci işlevi yürütmek hala işe yarıyor gibi görünüyor. Bu, aynı anda birden fazla işlevi belleğe almakla mı ilgili? Fmemo'nun üye değişkeni neden niçin bir tuhaflık tesadüf değildir?

Teşekkürler!

+0

Girinti doğru görünmüyor. İç içe geçmiş bir işlev mi? – MAK

+0

FTFY ........... – katrielalex

+1

BTW bu Python 3.2'de ['functools.lru_cache'] olarak uygulanmıştır (http://docs.python.org/dev/library/functools.html#functools .lru_cache). – katrielalex

cevap

12

İşlevler, tıpkı diğer her şey gibi nesneler olduğu için, bunların niteliklerini ayarlayabilirsiniz. Bkz:

>>> def foo(): pass 
>>> foo.x = 1 
>>> foo.x 
1 

ikinci-to-line fonksiyonu nesne üzerinde öznitelik olarak değerlerin iç önbellek setleri, böylece onu açığa. Bu, anımsanan bir işlevi alabileceğiniz ve onu aramak zorunda kalmadan, önbelleğiyle oynayabileceğiniz anlamına gelir. Bu uygun olabilir.


Örnek: kodun

>>> @memo 
... def id(x): return x 
>>> id(1) 
1 
>>> id(2) 
2 
>>> id.memo 
{(2,): 2, (1,): 1} 
+3

Buna ek olarak, kapanma nedeniyle * gerekli * olmadığını ekliyorum. Söylediğiniz gibi, ona müdahale etme ya da değerlere erişmeye gerek duymadan değerlere erişme yeteneği önemli bir şey olacaktır. –

+0

Aslında, kapalı 'table' değişkeni de önbellek (aslında' memo 'yeniden atanmışsa sorunludur) ... ama +1. –

+0

Gerçekten de, 'memo' yeniden atamak kötü olurdu. – katrielalex

İlgili konular