在Python的sys module裡,提供了一個API getrefcount()可以取得一個object的reference count是多少,回傳值是數字,而且回傳值應該會比你預期的值還要高,這是因為object在傳進getreference()時,reference count就會偷偷加一了。
看到下面的範例,a是一個Test的instance,reference count跟預期一樣是2(一個link到a,一個link到getrefcount的temporarily的變數),而b是一個list的instance,結果跟a一樣。
不過c跟d是一個string object,Python底層將c跟d link到同一個instance,所以在d='a'之後,c的reference count再加1。不過數字為何這麼地高,猜測應該是Python底層有自己去cache這些string object吧。
import sys class Test: def __init__(self, v): self.v = v a = Test(0) print id(a), sys.getrefcount(a) #>>> 19119440 2 b = list() print id(b), sys.getrefcount(b) #>>> 19135064 2 c = 'a' print id(c), sys.getrefcount(c) #>>> 18765728 18 d = 'a' print id(c), sys.getrefcount(c) #>>> 18765728 19 print id(d), sys.getrefcount(d) #>>> 18765728 19
---
題外話,研究一下Python的source code,
在CPython裡,每個PyObject都有一個記reference count的變數,此變數為ob_refcnt。所以可以自己寫一個get reference count的function。寫在c/c++ code裡,然後用SWIG轉成python module,取得Python object正確的reference count。
int GetReferenceCount(PyObject *obj) { return obj ? obj->ob_refcnt : 0; }
沒有留言:
張貼留言