Pythonにはすべての文字列のプールがあり、それらは(文字列)シングルトンですか?
より正確には、次のコードでは、1 つまたは 2 つの文字列がメモリ内に作成されていますか?
a = str(num)
b = str(num)
Pythonにはすべての文字列のプールがあり、それらは(文字列)シングルトンですか?
より正確には、次のコードでは、1 つまたは 2 つの文字列がメモリ内に作成されていますか?
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 の実装間、さらには同じ実装のバージョン間でも異なることに注意してください。
通常、文字列はインターンされません。あなたの例では、2 つの文字列が作成されます (0 から 9 までの値を除く)。これをテストするために、is
演算子を使用して、2 つの文字列が同じオブジェクトであるかどうかを確認できます。
>>> str(1056) is str(1056)
False