簡體   English   中英

引用計數在Python C擴展中

[英]reference counts in a Python C extension

我正在編寫我對Python的第一個C擴展,並且對我的引用計數感到困惑。 這就是我想要做的。

我在for循環中填充了一個dict:

mydict = PyDict_New();

for (...)
{
    pair = PyTuple_Pack(2, PyString_FromString("some string"),
          PyString_FromString("some other string"));

    /* at this point, the refcnt for the tuple is 1, the refcnts for the
       2 string items are 2. Because according to the source, PyString_FromString
       does an INCREF, and PyTuple_Pack() does an INCREF on its items
     */

    PyDict_SetItem(mydict, PyString_FromString("some key"), pair);

    /* At this point, the key's refcnt is 2.  PyString_FromString sets it to 1 and 
       PyDict_SetItem INCREF's it. Ditto for pair since PyDict_SetItem also INCREF's
       the value.
     */

    Py_DECREF(pair);

    /* pair's refcnt is 1 which makes sense to me since mydict now owns the tuple, 
       but the refcnt for its items are still at 2.  I don't understand this part.
     */
}

return mydict;

我的引用是否正確? 在C API文檔中,它特別建議使用PyObject_FromXXX函數作為PyTuple_SetItemPyList_SetItem參數,因為它們“竊取”引用。

沒有記錄PyDict_SetItem是否竊取了引用。 我猜它不是在哪種情況下,我應該這樣做

first = PyString_FromString("some string");
second = PyString_FromString("some other string");
pair = PyTuple_Pack(2, first, second);
Py_DECREF(second);
Py_DECREF(first);

我對嗎?

如果你看一下PyTuple_Pack的CPython源代碼(Objects / tupleobject.c),你會發現它確實增加了每個打包對象的引用計數。 如果您改為執行PyTuple_New后跟PyTuple_SetItem調用,則不需要減少引用計數,因為SetItem會竊取引用。

最后,您可能只想使用Py_BuildValue(“(ss)”,“some string”,“some other string”); 它將為您構建您的元組,它將為您創建PyStrings: http//docs.python.org/c-api/arg.html#Py_BuildValue

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM