2016-02-19 11 views
7

Nel codice sorgente Python, il metodo di creazione dell'oggetto int PyInt_FromLong, python crea un nuovo oggetto PyIntObject nella posizione del primo elemento di free_list che punta a. Ecco il codice:Come funziona il codice sorgente Python "free_list = (PyIntObject *) Py_TYPE (v);" sposta il puntatore free_list sull'oggetto successivo?

PyObject * 
PyInt_FromLong(long ival) 
{ 
    register PyIntObject *v; 
#if NSMALLNEGINTS + NSMALLPOSINTS > 0 
    if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { 
     v = small_ints[ival + NSMALLNEGINTS]; 
     Py_INCREF(v); 
     return (PyObject *) v; 
    } 
#endif 
    if (free_list == NULL) { 
     if ((free_list = fill_free_list()) == NULL) 
      return NULL; 
    } 
    /* Inline PyObject_New */ 
    v = free_list; 
    free_list = (PyIntObject *)Py_TYPE(v); 
    PyObject_INIT(v, &PyInt_Type); 
    v->ob_ival = ival; 
    return (PyObject *) v; 
} 

e Py_TYPE è:

#define Py_TYPE(ob)    (((PyObject*)(ob))->ob_type) 

Come funziona free_list = (PyIntObject *)Py_TYPE(v); lavoro?

Sposta free_list per puntare all'oggetto successivo nell'elenco.

Penso che Py_TYPE(v) restituirà PyInt_Type, quindi (PyIntObject *)PyInt_Type non sarà l'oggetto successivo.

risposta

4

Questo comportamento descritto nel commento sulla parte superiore del file:

free_list è una lista semplicemente legata di disposizione PyIntObjects, legata attraverso l'abuso dei loro ob_type membri.

Si potrebbe anche dare un'occhiata in fill_free_list funzione, che assegna PyIntObject s secondo il commento di intestazione:

static PyIntObject * 
fill_free_list(void) 
{ 
    PyIntObject *p, *q; 
    /* Python's object allocator isn't appropriate for large blocks. */ 
    p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock)); 
    if (p == NULL) 
     return (PyIntObject *) PyErr_NoMemory(); 
    ((PyIntBlock *)p)->next = block_list; 
    block_list = (PyIntBlock *)p; 
    /* Link the int objects together, from rear to front, then return 
     the address of the last int object in the block. */ 
    p = &((PyIntBlock *)p)->objects[0]; 
    q = p + N_INTOBJECTS; 
    while (--q > p) 
     Py_TYPE(q) = (struct _typeobject *)(q-1); 
    Py_TYPE(q) = NULL; 
    return p + N_INTOBJECTS - 1; 
} 

La linea principale è Py_TYPE(q) = (struct _typeobject *)(q-1);

+0

thx, haha, hanno bisogno di più attenzione da leggere il codice, grazie ancora. – weidwonder

+0

Sei sempre il benvenuto! – soon

Problemi correlati