Изменчивые и неизменные объекты - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь разобраться с изменчивыми и неизменными объектами.Я прочитал, что строка является неизменной и что для каждой строки создается отдельный объект с другим идентификатором объекта.Я пытаюсь проверить это с помощью приведенного ниже простого кода, однако, я вижу один и тот же идентификатор объекта для нескольких строк, которые не совпадают.Может кто-нибудь, пожалуйста, уточнить это.Заранее спасибо.

mystring = ""
mylist = ["This ", "That ", "This ", "That ", "This ", "That ", "This ", "That "]

for item in mylist:
    mystring = mystring + item
    print("mystring: ", mystring, "ID of mystring: ", id(mystring))

, что приводит к выводу ниже:

mystring:  This  ID of mystring:  6407264
mystring:  This That  ID of mystring:  42523448
mystring:  This That This  ID of mystring:  42523448
mystring:  This That This That  ID of mystring:  6417200
mystring:  This That This That This  ID of mystring:  42785608
mystring:  This That This That This That  ID of mystring:  42785608
mystring:  This That This That This That This  ID of mystring:  42837536
mystring:  This That This That This That This That  ID of mystring:  42775856

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

String являются неизменяемыми.Не существует метода str, который позволял бы изменять их.

При этом причина, по которой вы видите один и тот же идентификатор несколько раз, заключается в том, что когда объект больше не используется, Python будет повторно использовать свою позицию в памяти,И то, что делает id, это точно предоставить уникальный идентификатор, возвращая положение объекта в памяти.

Один из способов убедить себя в том, что это действительно причина для вашего наблюдения, состоит в том, чтобы всегдаиметь ссылку на каждую строку, которую вы создаете, добавляя их в list.

Код

mystring = ""
mylist = ["This ", "That ", "This ", "That ", "This ", "That ", "This ", "That "]

# A list to keep a reference to each string
created_strings = []

for item in mylist:
    mystring = mystring + item

    # Prevent mystring from being garbage collected by adding it to the list
    created_strings.append(mystring)

    print("mystring: ", mystring, "ID of mystring: ", id(mystring))

Выход

mystring:  This  ID of mystring:  2522900655888
mystring:  This That  ID of mystring:  2522903930416
mystring:  This That This  ID of mystring:  2522903930544
mystring:  This That This That  ID of mystring:  2522902118880
mystring:  This That This That This  ID of mystring:  2522900546624
mystring:  This That This That This That  ID of mystring:  2522900546864
mystring:  This That This That This That This  ID of mystring:  2522902428376
mystring:  This That This That This That This That  ID of mystring:  2522900907952

Обратите внимание, что теперь эта памятьне утилизируется, каждый объект имеет свой id.

0 голосов
/ 29 мая 2018

Python разрешено повторно использовать идентификаторы объектов для объектов с неперекрывающимися временами жизни, но вы видите повторное использование идентификаторов в тех случаях, когда должно быть перекрытие времени жизни.В частности, во время выполнения этого оператора:

mystring = mystring + item

между оценкой mystring + item и присвоением mystring, должно быть перекрытие времени жизни между любыми двумя последовательными значениями mystring.Вы видите повторное использование идентификатора для последовательных значений mystring, чего не должно быть.

Эффект, который вы видите, происходит из-за оптимизации в цикле вычисления байт-кода CPython, где операторы формы

string1 = string1 + string2

или

string1 += string2

, и если интерпретатор может подтвердить, что string1 не имеет других ссылок, он попытается выполнить сцепление путем мутации string1 на месте,Вы можете увидеть код в Python/ceval.c под unicode_concatenate.Эта оптимизация в основном невидима из-за проверки refcount, но влияние на значения id является одним из видимых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...