2017-02-21 5 views
9

Я пытаюсь понять, как неизменяемость работает в python. Поскольку строка является неизменной в python, я ожидал, что идентификатор будет меняться каждый раз, когда я выполняю операцию с строкой, но она не работает должным образом. пример: Последняя операция по t не меняет свой идентификатор. Любые идеи почему?Неизменяемость в Python

Screen shot of the operation

+0

Связанный: [об изменении идентификатора неизменяемой строки Python] (http://stackoverflow.com/questions/24245324/about-the-changing-id-of-a-python-immutable-string) – fredtantini

+1

Я действительно ненавижу, как эта оптимизация нарушает семантику языка Python. Согласно семантике языка, значения 't' до и после' + = 'должны быть разными объектами с (едва ли) перекрывающимися сроками жизни, поэтому для них не должно быть возможности делиться« id ». – user2357112

ответ

5

Я имел ряд яблок в различных клетках [memory containing variables (I will not go to the bit level)], некоторые из которых были пустыми [cells containing garbage/empty value].

Я взял один из них. Это было в ячейке 3 [logical address = 3].

Я нарисовал его синим (после того, как я клонировал его, используя будущие технологии, для демонстрации непреложности) [committed an operation on it, same could go for addition for integers].

Я посмотрел, где его положить, и хотя ячейка 4 была бесплатной, ячейка 3 была также (потому что «оригинальное» яблоко здесь больше нет)! Поэтому я вернул его в ячейку 3 [and although we get a "new" apple, it has the same address].


То же самое для вашего t (обратите внимание, что id это адрес памяти переменной в CPython), но так как мы говорим о «цепочках яблок» здесь (струны сделаны из последовательности символов, мы имеем рассмотреть объем пространства, мы должны продолжить последовательность, так что если у меня был моя память выглядит как (_ стендов для произвольных данных для мусора, «^» для пространства)

H e l l o _ _ _ _ _ B O O M 
^ string pointer points here 

, и я хотел бы изменить строку "Hello you", я мог бы рассмотреть возможность использования свободного места:

H e l l o^y o u _ B O O M 
^ string pointer points here 

Но если я хочу, чтобы изменить строку "Hello world!", я бы искать свободное пространство в длину "Hello world!" где-то еще (мы могли бы сразу после "BOOM", что вероятно в сборкой мусора среды, посмотрите, как ваши идентификаторы отличаются):

H e l l o^y o u _ B O O M _ H e l l o^w o r l d ! _ G A R B A G E 
          ^string pointer points here 
+0

@ B.M. Проблема заключается в сходстве с интернированием. Что я написал, в основном, как комментарий Martijn там - «Python может повторно использовать слоты памяти». ' – Uriel

+0

@ B.M.Я не могу понять, что вы подразумеваете под «Это не так [sic!]». Этот ответ описывает, что Python повторно использует адрес памяти для новой строки, потому что предыдущая строка получена из мусора. Я посмотрел на ссылку, и я не вижу, как это даст альтернативное объяснение явления, описанного в вопросе. –

+0

Извините, это было слишком прямо. Я отправляю что-то, чтобы объяснить, что я понял. Я думаю, что в этом примере синее яблоко не помещено в ячейку 3, вы просто отпустите зеленый цвет и добавьте синюю краску в конце ячейки 3. –

3

Идентификаторы объектов могут быть повторно использованы, если исходный объект больше не присутствует. Это не относится к строкам, а относится ко всем типам Python. Для простейшего примера, вы можете проверить идентификатор простого object:

>>> print id(object()) 
140437485756544 
>>> print id(object()) 
140437485756544 

Однако, если сохранить ссылку на предыдущий объект, идентификатор не будет повторно:

>>> a = object() 
>>> id(a) 
140437485756544 
>>> b = object() 
>>> id(b) 
140437485756560 

Вы можете воспроизводите то же поведение в тестах со строками, добавив промежуточные результаты (значения в t) в список.

+0

Почему в первых двух тестовых примерах добавления «Тест» к t произошла смена идентификатора? Является ли это «случайным» или у python есть систематический способ выделения памяти для строк в этом случае? – PrestonM

+1

@PrestonM Идентификатор не может быть повторно использован - что-то еще могло занять это место памяти (это как CPython реализует 'id') в первый раз. Гарантируется, что идентификатор живого объекта не изменится и что два разных (и живых) объекта не будут иметь один и тот же идентификатор. – user4815162342

+0

Это имеет смысл. Благодаря! – PrestonM

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