2014-06-27 10 views
9

Stavo seguendo il tutorial per definire 'nuovi tipi' in python, https://docs.python.org/2/extending/newtypes.html, e non ho capito lo scopo dell'utilizzo di Py_DECREF in questa parte di codice.Qual è lo scopo di Py_DECREF e PY_INCREF?

static PyObject * 
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 
{ 
    Noddy *self; 

    self = (Noddy *)type->tp_alloc(type, 0); 
    if (self != NULL) { 
     self->first = PyString_FromString(""); 
     if (self->first == NULL) 
      { 
      Py_DECREF(self); 
      return NULL; 
      } 

     self->last = PyString_FromString(""); 
     if (self->last == NULL) 
      { 
      Py_DECREF(self); 
      return NULL; 
      } 

     self->number = 0; 
    } 

    return (PyObject *)self; 
} 

La mia comprensione del conteggio dei riferimenti è irregolare e qualsiasi aiuto sarebbe apprezzato.

+0

Non vedo come questo codice possa confondere. Hai appena creato un oggetto ('self'), e' Py_DECREF' è chiamato per deallocarlo nel caso in cui qualcosa sia andato via durante la creazione delle stringhe ... cosa non è chiaro a riguardo? – Bakuriu

risposta

4

Il CPython Garbage Collector utilizza 'Conteggio di riferimento', cioè mantiene un elenco di riferimenti a un oggetto. Se il conteggio di riferimento di un oggetto cade a zero, allora implica che è sicuro per il garbage collector deallocare lo spazio per quell'oggetto.

Quindi, quando definiamo PyObjects è imperativo che noi chiamiamo esplicitamente Py_INCREF e Py_DECREF che aumentare e diminuire rispettivamente conteggi di riferimento di un oggetto.

7

In questo caso, Py_DECREF libererebbe semplicemente la memoria allocata con tp-> alloc.

tp-> alloc imposta il conteggio ref su 1. Py_DECREF diminuisce il conteggio ref da 1 a 0; poiché rileva che il conteggio ref è 0, chiama le funzioni appropriate per liberare la memoria (Noddy_dealloc in questo caso.)

Se una funzione C api Python restituisce NULL, qualcosa è andato storto; di solito viene impostata un'eccezione (salvata in una variabile globale).

Se il chiamante restituisce di nuovo NULL, l'eccezione è concatenata, da qui il 'ritorno NULL'.