2017-07-05 5 views
1

Ich arbeite mit Python C API in meinem C++ Programm und ich habe eine seltsame Sache bemerkt.Warum PyImport_ImportModule ein PyObject * mit einem Refcount von 3 statt 1 zurückgibt

Während ein einfaches Programm, wie dies in meinem Debugger auf meinem PC läuft:

int main(int argc, const char * argv[]) { 

    Py_Initialize(); 
    PyObject* scipy_stats_module = PyImport_ImportModule("scipy.stats"); // importing "scipy.stats" module 

    Py_DecRef(scipy_stats_module); 

    if (Py_FinalizeEx() < 0) { 
     PyErr_Print(); 
     exit(-1); 
    } 

    return 0; 

} 

ich gesehen habe, dass das ob_refcnt Attribut scipy_stats_module, direkt nach seiner Erstellung und vor Py_DecRef Aufruf, bei 3, während gesetzt Ich habe erwartet, dass es gleich 1 ist.

Kann mir jemand helfen zu verstehen, warum passiert das? Ist das ein Problem mit meinem Code oder ist das normal? Soll ich Py_DecRef dreimal oder nur einmal anrufen?

Vielen Dank!

P.S. Ich verwende Xcode 8.3.3 als IDE und Debugger auf meinem PC mit macOS 10.12.5

+0

Eine Referenz wird in 'sys.modules' dict gespeichert, nachdem ein Modul importiert wurde (Caching). Aber ich bin mir nicht sicher, woher der andere kommt. – freakish

+0

@freakish Ok, also ist es kein Problem mit meinem Code, nehme ich an. Aber sollte ich 'Py_DecRef' dreimal aufrufen, wenn ich' PyImport' oder etwas ähnliches wie 'PyObject_GetAttrString' verwende? Es scheint mir seltsam. – jackscorrow

+0

Ich glaube nicht. Sie sollten 'Py_DecRef' nur einmal aufrufen. Nachdem du damit gearbeitet hast. 'Py_Finalize' sollte sich um den Rest kümmern. Aber vielleicht solltest du darauf warten, dass jemand anderes es bestätigt. – freakish

Antwort

1

Sie besitzen nicht die einzige Referenz auf das neue Modul. In diesem Fall ist es einfach, die anderen Referenzen zu identifizieren - eine ist sys.modules['scipy.stats'], und eine ist das stats Attribut des scipy Modulobjekts - im Allgemeinen geht es nicht darum, welche anderen Referenzen ein Modul haben könnte.

Wenn Sie Ihren Verweis auf das Modul löschen, sollten Sie nur einmal Py_DECREF, weil Sie nur eine Referenz löschen, die Sie besitzen. Die anderen Referenzen existieren noch und müssen noch im Refcount berücksichtigt werden.

Verwandte Themen