1 回答

TA貢獻1111條經驗 獲得超0個贊
實際上,這個 dict 并沒有存儲在函數的本地命名空間中,它是一個自由變量,所以它存儲在函數閉包中。在 Python 2 中,請考慮:
In [1]: def cached(funcy):
...: cache = dict()
...: def cache_funcy(x):
...: if x in cache:
...: return cache[x]
...: else:
...: print cache
...: result = funcy(x)
...: cache[x] = result
...: return result
...: return cache_funcy
...:
...: @cached
...: def triple(x):
...: return 3*x
...:
In [2]: triple(1)
{}
Out[2]: 3
In [3]: triple(2)
{1: 3}
Out[3]: 6
現在:
In [5]: triple.func_closure
Out[5]:
(<cell at 0x10e4e7be8: dict object at 0x10e7ec910>,
<cell at 0x10e7b2590: function object at 0x10e81ede8>)
第一個單元格包含dict,第二個單元格包含正在裝飾的函數(它也是一個自由變量)。因此,您可以使用:
In [6]: triple.func_closure[0].cell_contents
Out[6]: {1: 3, 2: 6}
In [7]: triple.func_closure[0].cell_contents[2] = 'foo'
In [8]: triple(2)
Out[8]: 'foo'
注意,Python 3中函數的屬性有點不同,這里有一個直接的屬性__closure__,所以:
In [4]: triple.__closure__
Out[4]:
(<cell at 0x1026dbc78: dict object at 0x1028d1bd0>,
<cell at 0x1026dbf48: function object at 0x1028e59d8>)
實際上,在 Python 2 中,自 Python 2.6 起,添加了這些下劃線屬性是為了向前兼容,因此除非您使用的是低于 Python 2.6 的版本,否則該屬性也存在。
因此,出于兼容性原因,您可能應該使用 __closure__
添加回答
舉報