Id: примеры (PYTHON)

Функция id в Python: примеры и применение
Раздел: Встроенные функции, Интроспекция
id(object): int

Основы функции id

Функция id() в Python возвращает уникальный идентификатор (целое число) для указанного объекта. Этот идентификатор представляет адрес объекта в памяти CPython. Значение остается постоянным и уникальным в течение жизненного цикла объекта.

Функция используется для проверки, ссылаются ли две переменные на один объект в памяти. Это полезно при работе с изменяемыми типами данных и при отладке.

Синтаксис функции: id(object)

Параметры:

  • object - обязательный параметр, любой объект Python (число, строка, список, экземпляр класса и т.д.)

Возвращаемое значение:

  • Целое число, представляющее идентификатор объекта. В реализации CPython это адрес памяти объекта.

Особенности:

  • Идентификатор уникален для объекта в течение его существования
  • После удаления объекта идентификатор может быть переиспользован
  • Для проверки равенства идентификаторов обычно используется оператор is

Базовые примеры использования

Пример с различными типами данных:

x = 42
y = 'строка'
z = [1, 2, 3]

print(f'id(x) = {id(x)}')
print(f'id(y) = {id(y)}')
print(f'id(z) = {id(z)}')
id(x) = 140707231234432
id(y) = 2101454767984
id(z) = 2101455351104

Сравнение идентификаторов:

a = [1, 2, 3]
b = a
c = [1, 2, 3]

print(f'a is b: {a is b}')
print(f'id(a) == id(b): {id(a) == id(b)}')
print(f'a is c: {a is c}')
print(f'id(a) == id(c): {id(a) == id(c)}')
a is b: True
id(a) == id(b): True
a is c: False
id(a) == id(c): False

Идентификаторы для мелких целых чисел (интернирование):

a = 10
b = 10
c = 1000
d = 1000

print(f'id(a) == id(b): {id(a) == id(b)}')
print(f'id(c) == id(d): {id(c) == id(d)}')
id(a) == id(b): True
id(c) == id(d): False

Похожие функции в Python

Оператор is - проверяет, ссылаются ли две переменные на один объект. Более читаемая альтернатива сравнению id().

a = [1, 2, 3]
b = a
print(a is b)  # Вместо id(a) == id(b)
True

Функция hash() - возвращает хеш-значение объекта. Для неизменяемых объектов хеш обычно основан на идентификаторе, но не равен ему.

s = 'test'
print(f'id: {id(s)}, hash: {hash(s)}')
id: 2101454768048, hash: 3556498

Функция repr() с адресом - для некоторых объектов вывод включает адрес памяти.

lst = [1, 2, 3]
print(repr(lst))
[1, 2, 3]

Аналоги в других языках программирования

Java: метод System.identityHashCode() возвращает хеш-код, основанный на адресе объекта.

Object obj = new Object();
System.out.println(System.identityHashCode(obj));
356573597

JavaScript: прямого аналога нет, но можно использовать Map для отслеживания объектов.

const obj = {};
const weakMap = new WeakMap();
weakMap.set(obj, 'identifier');
console.log(weakMap.get(obj));
identifier

C#: метод RuntimeHelpers.GetHashCode() возвращает хеш-код по умолчанию.

object obj = new object();
Console.WriteLine(RuntimeHelpers.GetHashCode(obj));
58225482

PHP: функция spl_object_id() возвращает уникальный идентификатор объекта.

$obj = new stdClass();
echo spl_object_id($obj);
1

Типичные ошибки

Ожидание постоянства идентификаторов после удаления объекта:

x = [1, 2, 3]
id1 = id(x)
del x
y = [4, 5, 6]
id2 = id(y)
print(f'id1 == id2: {id1 == id2}')  # Может быть True
id1 == id2: True

Сравнение идентификаторов вместо значений:

a = 1000
b = 1000
if id(a) == id(b):
    print('Один объект')
else:
    print('Разные объекты')
Разные объекты

Использование id() для сравнения содержимого:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if id(list1) == id(list2):
    print('Списки равны')
else:
    print('Списки не равны')  # Этот вариант верный
Списки не равны

Изменения в последних версиях

В Python 3.8+ оптимизация интернирования строк была улучшена, что может влиять на идентификаторы часто используемых строк.

В Python 3.11 были внесены изменения в механизм выделения памяти, что может приводить к изменению паттернов значений, возвращаемых id(), но сама функция не меняла свой API.

Поведение функции остается стабильным с момента ее введения, так как она напрямую связана с внутренним представлением объектов в CPython.

Расширенные примеры

Отслеживание изменяемых объектов:

Пример python
class TrackingList(list):
    def __init__(self, *args):
        super().__init__(*args)
        self.initial_id = id(self)
    
    def check_modified(self):
        return self.initial_id != id(self)

lst = TrackingList([1, 2, 3])
print(f'Исходный ID: {lst.initial_id}')
lst.append(4)
print(f'Текущий ID: {id(lst)}')
print(f'Изменен: {lst.check_modified()}')
Исходный ID: 2101455351296
Текущий ID: 2101455351296
Изменен: False

Идентификаторы и сборка мусора:

Пример python
import gc

obj = {'data': 'test'}
obj_id = id(obj)
del obj
gc.collect()

# Новый объект может получить тот же ID
new_obj = ['new data']
print(f'Старый ID: {obj_id}, новый ID: {id(new_obj)}')
Старый ID: 2101455421184, новый ID: 2101455421184

Идентификаторы для элементов внутри структур данных:

Пример python
matrix = [[1, 2], [3, 4]]
ids = [id(row) for row in matrix]
print(f'ID строк: {ids}')

# Изменение одной строки не влияет на другие
matrix[0].append(5)
print(f'ID после изменения: {[id(row) for row in matrix]}')
ID строк: [2101455351424, 2101455351552]
ID после изменения: [2101455351424, 2101455351552]

Использование в слабых ссылках:

Пример python
import weakref

class Node:
    def __init__(self, value):
        self.value = value

node = Node(10)
node_id = id(node)
ref = weakref.ref(node)
print(f'ID объекта: {node_id}')
print(f'Через weakref: {id(ref()) if ref() else None}')

del node
print(f'После удаления: {ref()}')
ID объекта: 2101455460256
Через weakref: 2101455460256
После удаления: None

питон id function comments

En
Id Return identity of object