Идентифицируя объекты, почему изменяется возвращаемое значение из id(...)?

Идентификатор (объект)

Это целое число (или длинное целое число), которое гарантированно будет уникальным и постоянным для этого объекта в течение срока его службы.

Можете ли вы объяснить этот вывод? Почему jсмена ID?

>>> i=10  
>>> id(i)  
6337824  
>>> j=10  
>>> id(j)  
6337824  
>>> j=j+1  
>>> id(j)  
6337800  
>>> id(i)  
6337824  

8 ответов

Решение

Поскольку целые числа являются неизменяемыми, каждое целочисленное значение является отдельным объектом с уникальным идентификатором. Целое число 10 имеет другой идентификатор от 11, дела j=j+1 не изменяет значение существующего целочисленного объекта, скорее оно меняет j указывать на объект для 11,

Узнайте, что происходит, когда мы независимо создаем новую переменную k и назначьте ему значение 11:

>>> j=10
>>> id(j)
8402204
>>> j=j+1
>>> id(j)
8402192
>>> k=11
>>> id(k)
8402192

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

>>> x = 123456789
>>> id(x)
8404568
>>> y = 123456789
>>> id(y)
8404604

См. https://docs.python.org/3/c-api/long.html:

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

Вот почему 2**8 is 2**8 == True, а также 2**9 is 2**9 == False,

Значения от -5 до 256 предварительно распределяются.

Такой же id для разных переменных это продукт того, как Python создает переменные.

id является хешем расположения объекта в памяти. Переменные Python - это ссылки на объект, а не новые объекты. Если несколько переменных ссылаются на один и тот же объект, они имеют одинаковый идентификатор.

В CPython id как правило, происходит от Py_ObjectЗначение указателя, то есть его местоположение в памяти.

Python кэширует неизменяемые объекты (читайте целые числа и кортежи...) - вот почему они неизменяемы и экономят память, если во многих местах вы ссылаетесь на одну и ту же неизменяемую. Так small целые числа, пустые кортежи и тому подобное фактически кэшируются во время выполнения Python, поэтому вы продолжаете получать один и тот же объект и, следовательно, один и тот же идентификатор.

Попробуйте это для списка, вы не получите тот же идентификатор.

jID изменяется, потому что объект, названный j изменения. Сначала вы инициализируете j до 10, поэтому, когда вы звоните id(j) Вы получаете идентификатор 10, Затем вы установите j до 11, так что после этого, когда вы звоните id(j) Вы получаете идентификатор 11,

Дело в том, что каждый объект (значение) имеет уникальный идентификатор в Python, например объекты'hello'и'hi'иметь свои собственные идентификаторы или и11есть еще 2 разных идентификатора. Другое дело, что каждая переменная — это просто метка для определенного объекта (значения). Теперь, когда мы говорим, идентификатор объекта присваивается переменной. Затем, когда вы меняете значение (например,j=j+1), будет ссылаться на другой объект. Другими словами, станет меткой другого объекта. Таким образом, идентификатор меняется при изменении его значения. Существует также подход к кэшированию Python, который помогает ему быть более эффективным. Например, когда вы пишетеj=10иx=10вместо создания двух отдельных объектов создается только один объект10с 2 этикеткамиjиx.

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

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

Другие вопросы по тегам