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中实现的,但它们有时似乎有:
>>> 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的实现之间,甚至在同一实现的版本之间都会有所不同.
归档时间: |
|
查看次数: |
2917 次 |
最近记录: |