16

Pythonにはすべての文字列のプールがあり、それらは(文字列)シングルトンですか?

より正確には、次のコードでは、1 つまたは 2 つの文字列がメモリ内に作成されていますか?

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

4 に答える 4

24

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
于 2010-03-25T21:40:19.030 に答える
8

一般に、文字列は 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 の実装間、さらには同じ実装のバージョン間でも異なることに注意してください。

于 2010-03-25T21:40:55.113 に答える
2

通常、文字列はインターンされません。あなたの例では、2 つの文字列が作成されます (0 から 9 までの値を除く)。これをテストするために、is演算子を使用して、2 つの文字列が同じオブジェクトであるかどうかを確認できます。

>>> str(1056) is str(1056)
False
于 2010-03-25T21:35:09.983 に答える