Se unen las cuerdas en Python

¿Python tiene un grupo de todas las cadenas y están (cadenas) singletons allí?

Más preciso, en el siguiente código se crearon una o dos cadenas en la memoria:

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

?

Related of "Se unen las cuerdas en Python"

Las cadenas son inmutables en Python, por lo que la implementación puede decidir si realizar pasantías (que es un término a menudo asociado con C #, lo que significa que algunas cadenas se almacenan en un grupo) o no.

En tu ejemplo, estás creando dinámicamente cadenas. CPython no siempre busca en la agrupación para detectar si la cadena ya está allí, tampoco tiene sentido porque primero tiene que reservar memoria para crear la cadena y luego compararla con el contenido de la agrupación (ineficiente por mucho tiempo). instrumentos de cuerda).

Pero para cadenas de longitud 1, CPython busca en la agrupación (véase “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; } ... 

Asi que:

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

Pero cuando usa cadenas constantes directamente en su código, CPython usa la misma instancia de cadena:

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

En general, las cadenas no están internadas en Python, pero a veces parecen ser:

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

Esto no es infrecuente en Python, donde los objetos comunes pueden optimizarse de manera que los inusuales no lo son:

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

Y tenga en cuenta que todos estos tipos de detalles diferirán entre las implementaciones de Python e incluso entre las versiones de la misma implementación.

Las cuerdas no son internadas en general. En su ejemplo, se crearán dos cadenas (con la excepción de los valores entre 0 y 9). Para probar esto, podemos usar el operador is para ver si las dos cadenas son el mismo objeto:

 >>> str(1056) is str(1056) False 

la constante de grupo en python distingue grupo pequeño de enteros y grupo grande de enteros, y el grupo pequeño de enteros está en el rango en [-5, 257); y otros enteros en el grupo de enteros grandes. En Cython, si define una lista enlazada para almacenar estos datos, donde recuperar los datos se vuelve muy conveniente y rápido.

 # ifndef NSMALLPOSINTS # define NSMALLPOSINTS 257 # endif # ifndef NSMALLNEGINTS # define NSMALLNEGINTS 5 # endif # if NSMALLPOSINTS + NSMALLNEGINTS > 0 static PyIntObject * small_ints[NSMALLPOSINTS + NSMALLNEGINTS]; # endif 

Por cierto: el entero 257 puede ser extraño; Si dos objetos que tienen los mismos valores están en el mismo campo, su dirección puede ser o no la misma, depende del contexto del proceso; mientras que, si están en los diferentes campos, sus direcciones deben ser diferentes

y, por cierto, según el tipo de cadena, cython también proporciona un conjunto constante de que la longitud de la cadena debe ser una, mientras que puede no ser el mismo objeto

 a = str(11) b = str(11) print a == b # True print a is b # False c = str("A") d = str("A") print c == d # True print c is d # True aa = 12 bb = 12 print aa == bb # True print aa is bb # True cc = 333 dd = 333 print cc == dd # True print cc is dd # False 

Comparando sus direcciones, está obteniendo de forma transparente las soluciones a futuro.