2013-06-16 12 views
12

Per quanto ne so, tutto è oggetto in Python e l'id () dovrebbe restituire un numero diverso per ogni oggetto (giusto?Stesso valore per id (float)

Nel mio caso, id(1) rendimenti 4298178968, id(2) restituisce 4298178944 ma ottengo gli stessi valori per tutti i tipi float, id(1.1) restituisce 4298189032, id(2.2) restituisce anche 4298189032 e altro ancora.

Perché ottengo lo stesso id per tutti i valori float?

risposta

18

Python può riutilizzare le posizioni di memoria.

Quando si esegue:

id(1.1) 

si crea un valore float, per chiedere la sua id(), e poi Python cancella di nuovo il valore perché nulla si riferisce ad esso. Quando quindi si crea un altro valore float, Python può riutilizzare la stessa posizione di memoria e quindi id(2.2) è probabile che torni lo stesso valore per id():

>>> id(1.1) 
140550721129024 
>>> id(2.2) 
140550721129024 

fare questo, invece:

float_one, float_two = 1.1, 2.2 
print id(float_one), id(float_two) 

Ora la i valori float hanno riferimenti a loro (le due variabili) e non verranno distrutti e ora hanno diverse posizioni di memoria e quindi valori id().

La ragione per cui si visualizzano diversi valori id() per numeri interi piccoli (da -5 a 256) è perché these values are interned; Python crea solo uno1 oggetto intero e lo riutilizza più e più volte. Di conseguenza, questi numeri interi hanno tutti un aspetto di memoria univoco, poiché l'interprete Python stesso si riferisce a loro e non li cancellerà fino a quando l'interprete non si chiude.

+0

Ah, sì, ero in ipython dove i numeri sono memorizzati in Out! :) –

+0

Grazie a @MartijnPieters. – ehsandotnet

+0

Si noti che questo internamento dei piccoli numeri interi è probabilmente una caratteristica dell'implementazione di CPython piuttosto che una proprietà garantita del linguaggio. In questo caso, è simile ai valori NSInteger di piccole dimensioni (da 0 a 12 dalla memoria) in alcune implementazioni Objective-C in cui le persone si sono interrogate sullo strano numero di trattini. E, così, probabilmente non è una buona idea affidarsi a questo internamento. – paxdiablo

4
>>> id(1.1) 
154154684 

Come 1.1 non è stato assegnato ad una variabile quindi è garbage collection e la prossima volta lo stesso id sta per essere utilizzato per un float:

>>> id(2.2) 
154154684 

Salva 1.1 in una variabile:

>>> f = 1.1 
>>> id(f) 
154154684 #this id is locked for now 

Ora nuovo indirizzo viene utilizzato:

>>> id(1.1) 
154154700 
>>> id(2.2) 
154154700 

Questo vale per interi così:

>>> id(260) 
154302180 
>>> id(280) 
154302180 

interi da -5 a 256 vengono effettivamente memorizzati nella cache in pitone, in modo che siano sempre andando a tornare ID diversi.("is" operator behaves unexpectedly with integers)

Per stringhe:

Come interi alcune stringhe sono anche memorizzati nella cache in Python. Così, id di tali stringhe sta per essere diversi (Per i dettagli leggere: 'is' operator behaves differently when comparing strings with spaces):

>>> id('foo') 
162861592 
>>> id('foo') 
162861568 

stringa non alfanumerici (usa lo stesso id):

>>> id('foo!&9((&') 
162840000 
>>> id('foo!&9((&') 
162840000 
Problemi correlati