Python 是否有一个包含所有字符串的池,它们是(字符串)单例吗?
更准确地说,在下面的代码中,是在内存中创建了一个还是两个字符串?
a = str(num)
b = str(num)
Python 是否有一个包含所有字符串的池,它们是(字符串)单例吗?
更准确地说,在下面的代码中,是在内存中创建了一个还是两个字符串?
a = str(num)
b = str(num)
字符串在 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
一般来说,字符串不会在 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 的实现之间会有所不同,甚至在同一实现的不同版本之间也会有所不同。
字符串通常不被实习。在您的示例中,将创建两个字符串(0 到 9 之间的值除外)。为了测试这一点,我们可以使用is
运算符来查看两个字符串是否是同一个对象:
>>> str(1056) is str(1056)
False
python中pool的常量区分小整数池和大整数池,小整数池的范围在[-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
顺便说一句:整数 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
比较他们的地址,显然是领先的解决方案