2011-12-16 20 views
11

में संदर्भ संख्या मैं पाइथन में अपना पहला सी एक्सटेंशन लिख रहा हूं और मेरे संदर्भ गणनाओं के बारे में उलझन में हूं। यहां मैं जो करने की कोशिश कर रहा हूं वह यहां है।संदर्भ पाइथन सी एक्सटेंशन

मैं पाश के लिए एक में एक 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; 

मेरी रेफरी की गिनती सही हैं? सी एपीआई दस्तावेज़ों में, यह विशेष रूप से PyObject_FromXXX फ़ंक्शंस PyTuple_SetItem या PyList_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); 

मैं सही हूँ क्या करना चाहिए?

+0

इस सवाल से संबंधित लगता है: http://stackoverflow.com/questions/6977161/where-should-i-put-py-incref- और-py-decref-on-this-block-in-python-c-extension – Daenyth

+0

संबंधित हां लेकिन डुप्लिकेट नहीं: PyTuple बनाम PyDict – gecco

उत्तर

3

यदि आप PyTuple_Pack के लिए CPython स्रोत कोड (ऑब्जेक्ट्स/tupleobject.c) देखते हैं, तो आप देखेंगे कि यह वास्तव में प्रत्येक पैक ऑब्जेक्ट पर संदर्भ गणना बढ़ाता है। यदि आप इसके बजाय PyTuple_New को PyTuple_SetItem कॉल करते हैं, तो आपको संदर्भ संख्याओं को कम करने की आवश्यकता नहीं होगी क्योंकि SetItem संदर्भों को चुरा लेता है।

अंत में, आप बस Py_BuildValue ("(एसएस)", "कुछ स्ट्रिंग", "कुछ अन्य स्ट्रिंग") का उपयोग करना चाहते हैं; यह आप के लिए अपने टपल का निर्माण करेगा और यह आपके लिए PyStrings पैदा करेगा: http://docs.python.org/c-api/arg.html#Py_BuildValue

संबंधित मुद्दे