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}') # Может быть Trueid1 == 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.
Расширенные примеры
Отслеживание изменяемых объектов:
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
Идентификаторы и сборка мусора:
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
Идентификаторы для элементов внутри структур данных:
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]
Использование в слабых ссылках:
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