2010-03-25 19 views
8

Python ha un pool di tutte le stringhe e sono single (stringhe) singleton?Le stringhe sono raggruppate in Python

più precisa, nel seguente codice di uno o due stringhe sono stati creati nella memoria:

a = str(num) 
b = str(num) 

?

+4

Solo per riferimento, le stringhe non possono essere singleton. Un singleton è una classe per la quale può esserci solo un'istanza e quell'istanza deve essere accessibile a livello globale. Ci possono (si spera) essere molte istanze della classe 'str'; quindi non è un singleton. – zneak

+10

Il concetto che stai cercando è internazione stringa: http://en.wikipedia.org/wiki/String_interning –

+0

@zneak Grazie per il tuo commento. Intendevo qualcosa come value-singleton (pool o string interning è la parola giusta per esso - http://en.wikipedia.org/wiki/String_interning). –

risposta

16

stringhe sono immutabili in Python, quindi l'attuazione possono decidere se intern (che è un termine spesso associato con C#, o che alcune stringhe siano memorizzate in un pool) stringhe o meno.

Nel tuo esempio, stai creando dinamicamente stringhe. CPython fa non sempre guarda nel pool per rilevare se la stringa è già lì - non ha senso perché devi prima riservare la memoria per creare la stringa, e poi confrontarla con il contenuto della piscina (inefficiente per stringhe lunghe).

Ma per stringhe di lunghezza 1, CPython ha un aspetto in piscina (cfr "stringobject.c"):

static PyStringObject *characters[UCHAR_MAX + 1]; 

... 

PyObject * 
PyString_FromStringAndSize(const char *str, Py_ssize_t size) 
{ 

... 

    if (size == 1 && str != NULL && 
    (op = characters[*str & UCHAR_MAX]) != NULL) 
    { 
     #ifdef COUNT_ALLOCS 
      one_strings++; 
     #endif 

     Py_INCREF(op); 
     return (PyObject *)op; 
    } 

... 

Quindi:

a = str(num) 
b = str(num) 
print a is b # <-- this will print False in most cases (but try str(1) is str(1)) 

Ma quando si utilizza costanti stringhe direttamente nel tuo codice, CPython utilizza la stessa istanza di stringa:

a = "text" 
b = "text" 
print a is b # <-- this will print True 
+0

@Andidog: Se CPython non esamina il pool per verificare se la stringa è già presente, allora perché print a è b print true quando num è uguale a 5? – Brian

+0

@Brian: Scusa, è stato un po 'impreciso. Modificato la mia risposta per spiegare come implementa CPython. – AndiDog

+3

Buona risposta. L'unico dettaglio che aggiungo è che Python ha 'intern()' – keturn

1

Le stringhe non sono internate in generale. Nel tuo esempio verranno create due stringhe (ad eccezione dei valori compresi tra 0 e 9). Per verificare questa possiamo usare l'operatore is per vedere se le due stringhe sono lo stesso oggetto:

>>> str(1056) is str(1056) 
False 
+1

Che dire questo: In [1]: x = str (5) In [2]: y = str (5) In [3]: id (x) Out [3]: 3077925280L In [4]: ​​id (y) Out [4]: ​​3077925280L ? – gruszczy

+0

gruszczy: Questa è una buona domanda. Questo è un caso speciale che si applica solo ai numeri da 0 a 9.In generale, tuttavia, l'affermazione non è vera. Ho chiarito la mia risposta. –

+0

0 a 9 è un caso specifico su un compilatore specifico (sebbene, ammettiamolo, è il compilatore che la maggior parte delle persone usa). Altri compilatori possono scegliere un numero diverso di stringhe predefinite. – Brian

5

In generale, le stringhe non sono internati in Python, ma lo fanno a volte sembrano essere:

>>> str(5) is str(5) 
True 
>>> str(50) is str(50) 
False 

Questo non è raro in Python, in cui gli oggetti comuni potrebbero essere ottimizzati in modo che quelle insolite non sono:

>>> int(5+0) is int(5+0) 
True 
>>> int(50+0) is int(50+0) 
True 
>>> int(500+0) is int(500+0) 
False 

E tenere a mente, tutti questi tipi di dettagli differiranno tra le implementazioni di Python e anche tra le versioni della stessa implementazione.

Problemi correlati