2017-01-13 1 views
1

verwenden Ich frage mich, wie PyDict_SetDefault ohne Erstellen einer Referenz-Count-Katastrophe verwenden.Wie PyDict_SetDefault in Bezug auf die Reference-Anzahl von Standard

Die Dokumentation sagt nichts über eine gestohlene Referenz und einige Tests zeigen, dass es nicht "die Referenz" von default stehlen. Aber es erhöht es wenn und nur wenn der Schlüssel nicht im Wörterbuch vorhanden war.

Das scheint mir wirklich kompliziert, weil es einfach zu leicht ist, falsch zu verstehen. Ich benutze es zur Zeit wie folgt aus:

item = PyDict_SetDefault(dictionary, key, defaultvalue); 
if (item != defaultvalue) { 
    /* key was present, the item is a borrowed reference and default is at refcount 1.*/ 
    Py_INCREF(item);   /* item at refcount 2 */ 
    Py_DECREF(defaultvalue); /* default at refcount 0 */ 
    defaultvalue= NULL; 
} else { 
    /* key wasn't present, item is default and has refcount 2. */ 
    defaultvalue = NULL; 
} 

Am Ende das Wörterbuch und ich besitze eine Referenz für item und default wurde sauber gelöscht, nicht wahr?

Gibt es eine bessere Möglichkeit, mit der Situation umzugehen, ohne explizit zu überprüfen, ob item == default ich verpasst habe? Ist es wirklich so kompliziert oder habe ich die offensichtliche und einfache Art und Weise vermissen?

Antwort

1
item = PyDict_SetDefault(dictionary, key, defaultvalue); 
Py_INCREF(item); 
Py_DECREF(defaultvalue); 

Es ist nicht wirklich wichtig, ob item==defaultvalue - was auch immer passiert, Sie Eigentum an item nehmen (durch increfing) und lassen Sie das Eigentum an defaultvalue (durch decrefing, Sie unter der Annahme, wollen sie nicht für etwas anderes zu verwenden,).

Wenn key im Wörterbuch vorhanden ist, wird defaultvalue nicht verwendet, daher bleibt der Refcount auf 1 und wird mit decrf zerstört. item ist mit einem refcount von 1 zurück (weil es im Wörterbuch gespeichert ist) und wir erhöhen es, weil wir es auch so item hat jetzt eine refcount von 2.

Wenn key verwenden nicht vorhanden ist, dann defaultvalue gespeichert im Wörterbuch (Refcount jetzt 2) verwendet und zurückgegeben. item und defaultvalue sind gleich. Wir inkrementieren item (refcount 3) das decref defaultvalue (refcount 2).

So oder so enden wir am selben Ort.