字符串是否在Python中汇集

Nik*_*hhi 10 python memory string singleton string-interning

Python是否拥有所有字符串的池并且它们是(字符串)单例吗?

更准确地说,在下面的代码中,在内存中创建了一个或两个字符串:

a = str(num)
b = str(num) 
Run Code Online (Sandbox Code Playgroud)

And*_*Dog 19

字符串在Python中是不可变的,因此实现可以决定是否实习(这是一个通常与C#相关联的术语,意味着某些字符串存储在池中)字符串与否.

在您的示例中,您将动态创建字符串.CPython并不总是查看池以检测字符串是否已经存在 - 它也没有意义,因为您首先必须保留内存以创建字符串,然后将其与池内容进行比较(长时间效率低下)字符串).

但对于长度为1的字符串,CPython会查看池(参见"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;
    }

...
Run Code Online (Sandbox Code Playgroud)

所以:

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

但是当在代码中直接使用常量字符串时,CPython使用相同的字符串实例:

a = "text"
b = "text"
print a is b # <-- this will print True
Run Code Online (Sandbox Code Playgroud)

  • 好答案.我要添加的唯一细节是要注意Python确实有`intern()` (3认同)

Ned*_*der 5

通常,字符串不是在Python中实现的,但它们有时似乎有:

>>> str(5) is str(5)
True
>>> str(50) is str(50)
False
Run Code Online (Sandbox Code Playgroud)

这在Python中并不罕见,在这种情况下,常见对象可能会以不寻常的方式进行优化:

>>> int(5+0) is int(5+0)
True
>>> int(50+0) is int(50+0)
True
>>> int(500+0) is int(500+0)
False
Run Code Online (Sandbox Code Playgroud)

请记住,所有这些细节在Python的实现之间,甚至在同一实现的版本之间都会有所不同.