在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;
}
沒有留言:
張貼留言