2017-02-09 50 views
0

下面是一個memoized階乘函數的簡單例子。它工作正常,我瞭解基本概念,但有一個細節讓我感到困惑。變量memory在哪裏?爲什麼在memoize()完成執行後仍然存在?它似乎不是一個全球變量,因爲我不能做類似print memory的事情。這裏發生了什麼?備忘python函數的緩存在哪裏存在?

def memoize(f): 
    memory = {} 
    def memoized(*args): 
     if args not in memory: 
      memory[args] = f(*args) 
     return memory[args] 
    return memoized 

@memoize 
def fact(n): 
    if n <= 1: 
     return 1 
    return n * fact(n - 1) 

print fact(10) 
+2

它存在於[closure](https://en.wikipedia.org/wiki/Closure_ (computer_programming))包裝'fact' –

+0

當你在另一個函數中聲明一個函數時,內部函數可以看到在外部函數中聲明的所有變量。它被稱爲封閉。 – Gabriel

回答

3

memory字典被存儲在「閉合」,這在創建時的功能的引用從包圍函數的局部變量。封閉包裝這些參考。

你可以看到字典爲fact.__closure__[1].cell_contents。 (fact.__closure__[0].cell_contents是原始未修飾的函數,它也通過類似的方式通過變量f引用裝飾函數。)

+0

不錯,我沒有意識到你可以輕鬆地反思封閉! –