Почему два индивидуально созданных неизменяемых объекта имеют одинаковый идентификатор, а изменяемые объекты имеют разные значения, хотя оба ссылаются на одни и те же значения?

Два индивидуально созданных изменяемых списка имеют разные идентификаторы.

Python SHELL: (изменяемый)

>>> mylist = ['spam', 'eggs']
>>> yourlist = ['spam', 'eggs']
>>> id(mylist), id(yourlist)
(49624456, 48910408)

В то время как две индивидуально созданные неизменяемые строки имеют одинаковые идентификаторы.

Python SHELL: (неизменяемый)

>>> a = 10
>>> b = 10
>>> id(a), id(b)
(507099072, 507099072)

a и b ссылаются на один и тот же объект? Если нет, то почему идентификаторы похожи? mylist и yourlist относятся к разным объектам? Если да, то почему у них разные идентификаторы.


person Yousuf Memon    schedule 13.01.2014    source источник
comment
по этой причине изменяемые объекты могут видоизменяться, список создается дважды, но если вы проверите идентификатор элемента 0 обоих списков, они должны быть идентичными. Поскольку списки изменяемы, вы не можете ожидать, что list будет указывать на один и тот же объект, даже если каждая ячейка внутри списка указывает на одни и те же неизменяемые объекты. По этой причине неизменяемые объекты не могут видоизменяться, python может оптимизировать их и предотвратить дублирование.   -  person Loïc Faure-Lacroix    schedule 13.01.2014


Ответы (1)


Python кэширует небольшие строки и числа: http://docs.python.org/2/c-api/int.html#PyInt_FromLong

Текущая реализация хранит массив целочисленных объектов для всех целых чисел от -5 до 256, когда вы создаете int в этом диапазоне, вы фактически просто возвращаете ссылку на существующий объект.

И id(some_list) всегда дает вам адрес контейнера - объект списка в памяти, а не строки в списке!

person ndpu    schedule 13.01.2014
comment
Есть ли способ создать две переменные с одинаковым значением от -5 до 256, но сделать их разными объектами? a = 2, b = 2, а затем a is b вернет True. Есть ли способ иметь оба со значением 2, но быть разными объектами? - person Jesse Zhuang; 11.09.2016
comment
@JesseZhuang я вижу только один способ - путем создания подклассов int. Все экземпляры вашего собственного целочисленного класса будут разными объектами... - person ndpu; 11.09.2016