字符串是否在Python中汇集

问题描述 投票:10回答:4

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

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

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

?

python string memory singleton string-interning
4个回答
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;
    }

...

所以:

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

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

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

5
投票

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

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

这在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

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


1
投票

字符串一般不会被拘留。在您的示例中,将创建两个字符串(0到9之间的值除外)。为了测试这个,我们可以使用is运算符来查看两个字符串是否是同一个对象:

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

0
投票

python中池的常量区分小整数池和大整数池,小整数池的范围为[-5,257);和大整数池中的其他整数。在Cython中,如果定义了一个链表来存储这些数据,那么获取数据变得非常方便和快捷。

# ifndef NSMALLPOSINTS
    # define NSMALLPOSINTS 257
# endif

# ifndef NSMALLNEGINTS
    # define NSMALLNEGINTS 5
# endif

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

BTW:整数257可能比较陌生;如果两个具有相同值的对象在同一个字段中,则它们的地址可能相同或不相同,这取决于过程的上下文;然而,如果他们在不同的领域,他们的地址必须是不同的

顺便说一句,根据字符串类型,cython还提供一个常量池,字符串的长度应为1,而它可能不是同一个对象

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

比较他们的地址,透明地获得领先的解决方案

© www.soinside.com 2019 - 2024. All rights reserved.