Python是否有一個所有字符串池,並且它們是(字符串)單例嗎?在Python中彙集字符串
a = str(num)
b = str(num)
:
更精確的,在下面的代碼的一個或兩個字符串是在存儲器中創建?
Python是否有一個所有字符串池,並且它們是(字符串)單例嗎?在Python中彙集字符串
a = str(num)
b = str(num)
:
更精確的,在下面的代碼的一個或兩個字符串是在存儲器中創建?
字符串是Python中不變的,所以實現可以決定是否實習生(這是經常與C#相關的術語,這意味着某些字符串存儲在一個池中)或不是。
在您的示例中,您正在動態創建字符串。 CPython確實並不總是查看池以檢測字符串是否已經存在 - 這也沒有意義,因爲您首先必須保留內存才能創建字符串,然後將其與池內容進行比較(效率低下對於長字符串)。
但長度爲1的字符串,CPython的不看入池(參見 「stringobject.c」):使用不斷字符串時
a = str(num)
b = str(num)
print a is b # <-- this will print False in most cases (but try str(1) is str(1))
但是:
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;
}
...
所以直接在您的代碼中,CPython使用相同的字符串實例:
a = "text"
b = "text"
print a is b # <-- this will print True
字符串通常不是實習的。在你的例子中,將創建兩個字符串(0和9之間的值除外)。爲了驗證這一點,我們可以使用is
操作者看到,如果兩個字符串相同的對象:
>>> str(1056) is str(1056)
False
什麼樣: 在[1]:X = STR(5) 在[2]:Y = STR(5) 在[3]:ID(x)的 缺貨[3]:3077925280L In [4]:id(y) Out [4]:3077925280L ? – gruszczy 2010-03-25 21:38:04
gruszczy:這是一個很好的問題。這是一個特殊情況,只適用於數字0到9。但總的來說,這個陳述是不正確的。我澄清了我的答案。 – 2010-03-25 21:50:32
0到9是特定編譯器的特定情況(儘管承認它是大多數人使用的編譯器)。其他編譯器可以選擇不同數量的預定義字符串。 – Brian 2010-03-25 21:58:39
一般情況下,字符串不是用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的實現和甚至是相同實現的版本之間都會有所不同。
僅供參考,字符串不能是單身。單例是一個只能有一個實例的類,並且該實例必須是全局可訪問的。可以(希望)有'str'類的許多實例;因此它不是一個單身人士。 – zneak 2010-03-25 21:36:30
你正在尋找的概念是字符串實習:http://en.wikipedia.org/wiki/String_interning – 2010-03-25 21:39:17
@zneak謝謝你的評論。我的意思是像價值單身(池或字符串實習是正確的詞 - http://en.wikipedia.org/wiki/String_interning)。 – 2010-03-25 21:44:06