Есть ли у Python пул из всех строк и являются ли они (строки) синглтонами?Строки, объединенные в Python
Более точно, в следующем коде были созданы одна или две строки в памяти:
a = str(num)
b = str(num)
?
Есть ли у Python пул из всех строк и являются ли они (строки) синглтонами?Строки, объединенные в Python
Более точно, в следующем коде были созданы одна или две строки в памяти:
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
@Andidog: Если CPython не смотрит в пул, чтобы проверить, существует ли строка там, то почему print a является b print true, когда num равно 5? – Brian
@Brian: Извините, это было немного неточно. Отредактировал мой ответ, чтобы объяснить, как CPython реализует это. – AndiDog
Хороший ответ. Единственная деталь, которую я бы добавил, это отметить, что у Python есть 'intern()' – keturn
Строки не являются интернированными в целом. В вашем примере будут созданы две строки (за исключением значений от 0 до 9). Чтобы проверить это, мы можем использовать оператор is
, чтобы увидеть, если эти две строки и тот же объект:
>>> str(1056) is str(1056)
False
Что об этом: В [1]: X = Str (5) В работе [2]: Y = ул (5) В работе [3]: Идентификатор (х) Из [3]: 3077925280L В [4]: id (y) Out [4]: 3077925280L ? – gruszczy
gruszczy: Это хороший вопрос. Это особый случай, который применяется только к числам от 0 до 9.В общем, это утверждение неверно. Я уточнил свой ответ. –
От 0 до 9 - конкретный случай на конкретном компиляторе (хотя, по общему признанию, это компилятор, который использует большинство людей). Другие компиляторы могут выбрать другое количество предварительно определенных строк. – Brian
В общем, строки не интернировали в 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 и даже между версиями одной и той же реализации.
Только для справки, строки не могут быть одиночными. Singleton - это класс, для которого может быть только один экземпляр, и этот экземпляр должен быть доступен глобально. Там может (надеюсь) быть множество экземпляров класса 'str'; поэтому он не синглтон. – zneak
Концепция, которую вы ищете, - это перевод строки: http://en.wikipedia.org/wiki/String_interning –
@zneak Спасибо за комментарий. Я имел в виду что-то вроде value-singleton (правильное слово для пула или строки - http://en.wikipedia.org/wiki/String_interning). –