Question

Est-ce que Python a une piscine de toutes les chaînes et sont-ils (cordes) singletons là-bas?

Plus précisément, dans le code suivant une ou deux chaînes ont été créées en mémoire:

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

Était-ce utile?

La solution

Les chaînes sont immuables en Python, de sorte que la mise en œuvre peut décider de stagiaire (c'est un terme souvent associé à C #, ce qui signifie que certaines chaînes sont stockées dans une piscine) chaînes ou non.

Dans votre exemple, vous créez dynamiquement des chaînes. CPython fait pas toujours regarder dans la piscine pour détecter si la chaîne est déjà là - il n'a pas de sens parce que vous aussi devez d'abord réserver la mémoire pour créer la chaîne, puis le comparer à le contenu de la piscine (inefficace pour les longues chaînes).

Mais pour les chaînes de longueur 1, CPython ne regarde dans la piscine (cf. "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;
    }

...

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

Mais lorsque vous utilisez constante chaînes directement dans votre code, CPython utilise la même instance de chaîne:

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

Autres conseils

En général, les chaînes ne sont pas internées en Python, mais ils ne semblent parfois être:

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

Ce n'est pas rare en Python, où des objets communs peuvent être optimisés de manière à les inhabituelles ne sont pas:

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

Et gardez à l'esprit, toutes ces sortes de détails différeront entre les implémentations de Python, et même entre les versions de la même application.

Les chaînes ne sont pas internées en général. Dans votre exemple, deux chaînes seront créées (à l'exception des valeurs comprises entre 0 et 9). Pour tester cela, nous pouvons utiliser l'opérateur is pour voir si les deux chaînes sont le même objet:

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

la constante de piscine en python distinguer piscine petit entier et un grand pool de nombre entier, et la piscine petit entier est la gamme de [-5, 257); et d'autres nombres entiers dans la grande piscine entière. En Cython, si définit une liste chaînée pour stocker ces données, où chercher les données devient très pratique et rapide.

# ifndef NSMALLPOSINTS
    # define NSMALLPOSINTS 257
# endif

# ifndef NSMALLNEGINTS
    # define NSMALLNEGINTS 5
# endif

# if NSMALLPOSINTS + NSMALLNEGINTS > 0
    static PyIntObject * small_ints[NSMALLPOSINTS + NSMALLNEGINTS];
# endif

BTW: le nombre entier 257 peut-être étranger; si deux objets qu'ils ont les mêmes valeurs sont dans le même domaine, leur adresse peut être ou ne pas être le même, cela dépend du contexte du processus; alors que, si elles sont dans les différents domaines, leurs adresses doivent être différence

et par ailleurs, selon le type de chaîne, cython fournissent également une piscine constante que la longueur de chaîne doit être un, alors il peut être pas le même objet

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

comparer leurs adresses, est d'obtenir de manière transparente les solutions à venir

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top