2014-07-17 15 views
6

Creiamo due liste:oggetti Python senza nome hanno la stessa id

x = range(3) 
y = range(3) 
print id(x), id(y) 

Out:

4366592912 4366591040 

ho creato due liste indipendenti, e l'output mostra due diversi indirizzi di memoria. Questo non è sorprendente. Ma ora facciamo la stessa cosa senza l'assegnazione:

id(range(3)) 

Out:

4366623376 

e una seconda volta:

id(range(3)) 

Out:

4366623376 

Sono non so come interpretarlo. Perché questi due elenchi senza nome hanno lo stesso indirizzo di memoria?

+4

"Due oggetti con vite non sovrapposte possono avere lo stesso valore id()" https://docs.python.org/3.4/library/functions.html#id –

+0

Leggermente correlato: http://stackoverflow.com/domande/23777801/python-slice-metodo-fa-non-sempre-ritorno-a-new-indirizzo-in-memory –

risposta

13

From the doc of id(object):

Ritorna la “identità” di un oggetto. Questo è un numero intero che è garantito essere unico e costante per questo oggetto durante la sua vita. Due oggetti con vite non sovrapposte possono avere lo stesso valore id().

Poiché le due catene all'interno dei id() chiamate hanno vite non sovrapposti, i loro valori id possono essere uguali.

I due intervalli assegnati alle variabili hanno una durata di sovrapposizione di pertanto devono avere valori di ID diversi.

Edit:

uno sguardo al sorgenti C ci mostra builtin_id:

builtin_id(PyObject *self, PyObject *v) 
{ 
    return PyLong_FromVoidPtr(v); 
} 

e per PyLong_FromVoidPtr.

PyLong_FromVoidPtr(void *p) 
{ 
#if SIZEOF_VOID_P <= SIZEOF_LONG 
    return PyLong_FromUnsignedLong((unsigned long)(Py_uintptr_t)p); 
#else 

#ifndef HAVE_LONG_LONG 
# error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long" 
#endif 
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P 
# error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" 
#endif 
    return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p); 
#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ 

} 

Quindi l'ID è un indirizzo di memoria.

0

Il primo oggetto non è più compreso nel momento in cui viene creato il secondo oggetto.

Non so se python sia un po 'intelligente sotto il cofano e riconosca che il secondo oggetto è esattamente uguale al primo oggetto (che ora è fuori ambito) e semplicemente riutilizzando lo stesso indirizzo per esso?

Problemi correlati