1

Изначально переменные a, b и c имеют значение 1 и тот же адрес. Когда переменная a увеличивается на 1, адрес изменяется, а адрес переменных b и c остается таким же. Может ли кто-нибудь уточнить этот адрес?Назначение адресов Python для переменных

Также теперь, когда переменная b увеличивается на 1, а адрес b теперь равен адресу a. Может ли кто-то прокомментировать это?

>>> a = 1 
>>> b = a 
>>> c = b 
>>> a += 1 
>>> print a,b,c 
2 1 1 
>>> id(a) 
26976576 
>>> id(b) 
26976600 
>>> id(c) 
26976600 
>>> b += 1 
>>> print a,b,c 
2 2 1 
>>> id(c) 
26976600 
>>> id(b) 
26976576 
>>> id(a) 
26976576 
+0

Пожалуйста, ознакомьтесь с http://nedbatchelder.com/text/names.html. Также обратите внимание, что вторая часть вашего вопроса - это деталь реализации - CPython ставит мелкие целые числа, это не поведение, на которое вы должны положиться. – jonrsharpe

ответ

0

Причина вы видите это происходит потому, что вы думаете в терминах переменных, a, b и c являющихся объектами, когда на самом деле это целые числа, которые являются объектами вашего примера. Расположение памяти, что вы смотрите на то, когда вы набираете id() это место для int объекта 1 и int объект 2, а не имена переменных a, b и c.

В python имена привязаны к объектам. Это может быть проблематично, если у вас есть такие типы, как lists, которые изменяются, и вы пытаетесь их скопировать. Изменение объекта означает, что при опросе обеих ссылок вы видите изменение, распространяемое в обоих, и это не всегда то, что вы намереваетесь, и если вы не знаете об этом, это может вызвать множество проблем с отладкой.

Обратно к вашему примеру, я добавил два примера id() в начале, чтобы показать идентификаторы целочисленных объектов 1 и 2. Это должно разъяснить вам все.

>>> a = 1 
>>> b = a 
>>> c = a 
>>> id(a) 
4298174296 
>>> id(b) 
4298174296 
>>> id(c) 
4298174296 
>>> id(1) 
4298174296 
>>> id(2) 
4298174272 
>>> a += 1 
>>> id(a) 
4298174272 
>>> id(b) 
4298174296 
>>> id(c) 
4298174296 
>>> b += 1 
>>> print a, b, c 
2 2 1 
>>> id(c) 
4298174296 
>>> id(b) 
4298174272 
>>> id(a) 
>>> 4298174272 

Как вы можете видеть, место для 1 и a b c изначально все-таки и место для 2 отличается. Затем, когда вы меняете назначение на a, оно указывает на местоположение 2, а b и c остается на 1.Затем, когда вы переназначаете b, он указывает на место для 2, оставив только c, указывая на 1.

Надеюсь, что это разъяснит вам.

1

https://docs.python.org/2/c-api/int.html#c.PyInt_FromLong

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

Кроме того, в Python Integer исходит из неизменяемого объекта: PyIntObject. Когда вы создадите PyIntObject, вы никогда не измените его значение, а остальные будут просто ссылкой.

1

Ценности и адреса памяти являются вводящими в заблуждение условиями. Подумайте об объектах, именах и идентификаторах. Сначала объекту 1 присвоены имена a, b и c. Таким образом, идентификатор этого объекта может быть достигнут всеми именами.

На втором этапе вы назначаете новый объект, целое число 2, с другим идентификатором на имя a.

На третьем этапе вы также назначаете объект integer 2 на b. Это деталь реализации CPython, что маленькие целые числа хранятся только один раз в памяти, поэтому объект и, следовательно, его идентификатор, который достигнут по имени b, совпадает с a.