2013-03-27 11 views
5

Oggi ho imparato che Python memorizza nella cache l'espressione {}, e lo sostituisce con un nuovo dict vuota quando è assegnato ad una variabile:strano comportamento relative al apparente caching di "{}"

print id({}) 
# 40357936 

print id({}) 
# 40357936 

x = {} 
print id(x) 
# 40357936 

print id({}) 
# 40356432 

non ho guardato il codice sorgente, ma ho un'idea su come questo potrebbe essere implementato. (Forse quando il conteggio dei riferimenti al globale {} viene incrementato, il globale {} viene sostituito.)

ma considerare questo bit:

def f(x): 
    x['a'] = 1 
    print(id(x), x) 

print(id(x)) 
# 34076544 

f({}) 
# (34076544, {'a': 1}) 

print(id({}), {}) 
# (34076544, {}) 

print(id({})) 
# 34076544 

f modifica il dict globale senza inducendolo a essere sostituito, e stampa il dettato modificato Ma al di fuori di f, nonostante l'id sia lo stesso, il dict globale è ora vuoto!

Cosa sta succedendo ??

+0

potresti essere interessato anche a questo: http://stackoverflow.com/questions/15315096/why-the-id-of-an-object-would-change-depending-on-the-line-in-the -python-shell/15321863 # 15321863 – User

+0

Cassa molto interessante, grazie per la condivisione. – dimo414

+0

'id()' di Python utilizza un indirizzo di memoria (almeno nell'implementazione CPython) come ID per gli oggetti. È un identificatore univoco solo in un singolo punto nel tempo, non unico per l'intera durata del programma. Questo è esplicito nella documentazione: http://docs.python.org/2/library/functions.html#id –

risposta

6

Non viene memorizzato nella cache: se non si assegna il risultato di {} in qualsiasi punto, il suo conteggio di riferimenti è 0 e viene pulito immediatamente. È appena successo che il successivo che hai assegnato riutilizzasse la memoria di quella vecchia. Quando lo assegni a x lo tieni in vita, e poi il prossimo ha un indirizzo diverso.

Nel tuo esempio di funzione, una volta f restituisce non ci sono riferimenti rimanenti al tuo dettato, quindi viene pulito anche, e la stessa cosa si applica.

+0

Ottima risposta, grazie per aver spiegato che "il caching" (che pensavo fosse una sorta di ottimizzazione abbastanza dubbia, comunque) – valtron

4

Python non sta facendo alcun caching qui. Ci sono due possibilità quando id() dà lo stesso valore di ritorno in punti diversi del programma:

  1. id() stato chiamato sullo stesso oggetto due volte
  2. Il primo oggetto che id() stato invitato stato garbage collection prima del secondo oggetto è stato creato e il secondo oggetto è stato creato nella stessa posizione di memoria dell'originale

In questo caso, era il secondo. Ciò significa che anche se print id({}); print id({}) è possibile stampare lo stesso valore due volte, ogni chiamata si trova su un oggetto distinto.