2011-12-16 3 views
11

파이썬에 첫 번째 C 확장을 작성하고 있으며 참조 카운트에 대해 혼란 스럽습니다. 여기 내가하려는 일이있다. 파이썬 C 확장의 참조 횟수

나는 for 루프에서 딕셔너리를 채울 :
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_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- and-py-decref-on-this-python-c-extension – Daenyth

+0

관련이 있지만 중복되지는 않습니다 : PyTuple 대 PyDict – gecco

답변

3

PyTuple_Pack 용 CPython 소스 코드 (Objects/tupleobject.c)를 보면 포장 된 각 객체에 대한 참조 카운트가 실제로 증가한다는 것을 알 수 있습니다. 대신 PyTuple_SetItem 호출에 이어 PyTuple_New를 수행하면 SetItem이 참조를 도용하기 때문에 참조 카운트를 감소시킬 필요가 없습니다.

마지막으로 Py_BuildValue ("(ss)", "some string", "some other string")을 사용하기 만하면됩니다. 그것은 당신을 위해 튜플을 구축하고 당신을 위해 PyStrings을 생성합니다 : http://docs.python.org/c-api/arg.html#Py_BuildValue