2010-03-25 2 views
8

Есть ли у Python пул из всех строк и являются ли они (строки) синглтонами?Строки, объединенные в Python

Более точно, в следующем коде были созданы одна или две строки в памяти:

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

?

+4

Только для справки, строки не могут быть одиночными. Singleton - это класс, для которого может быть только один экземпляр, и этот экземпляр должен быть доступен глобально. Там может (надеюсь) быть множество экземпляров класса 'str'; поэтому он не синглтон. – zneak

+10

Концепция, которую вы ищете, - это перевод строки: http://en.wikipedia.org/wiki/String_interning –

+0

@zneak Спасибо за комментарий. Я имел в виду что-то вроде value-singleton (правильное слово для пула или строки - http://en.wikipedia.org/wiki/String_interning). –

ответ

16

Строки неизменны в 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 
+0

@Andidog: Если CPython не смотрит в пул, чтобы проверить, существует ли строка там, то почему print a является b print true, когда num равно 5? – Brian

+0

@Brian: Извините, это было немного неточно. Отредактировал мой ответ, чтобы объяснить, как CPython реализует это. – AndiDog

+3

Хороший ответ. Единственная деталь, которую я бы добавил, это отметить, что у Python есть 'intern()' – keturn

1

Строки не являются интернированными в целом. В вашем примере будут созданы две строки (за исключением значений от 0 до 9). Чтобы проверить это, мы можем использовать оператор is, чтобы увидеть, если эти две строки и тот же объект:

>>> str(1056) is str(1056) 
False 
+1

Что об этом: В [1]: X = Str (5) В работе [2]: Y = ул (5) В работе [3]: Идентификатор (х) Из [3]: 3077925280L В [4]: ​​id (y) Out [4]: ​​3077925280L ? – gruszczy

+0

gruszczy: Это хороший вопрос. Это особый случай, который применяется только к числам от 0 до 9.В общем, это утверждение неверно. Я уточнил свой ответ. –

+0

От 0 до 9 - конкретный случай на конкретном компиляторе (хотя, по общему признанию, это компилятор, который использует большинство людей). Другие компиляторы могут выбрать другое количество предварительно определенных строк. – Brian

5

В общем, строки не интернировали в 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 и даже между версиями одной и той же реализации.

Смежные вопросы