Давайте сначала выясним, что делает id()
:
Возвращает «идентичность» объекта. Это целое число, которое гарантированно будет уникальным и постоянным для этого объекта в течение его жизни. Два объекта с неперекрывающимися временами жизни могут иметь одинаковое значение id ().
Сведения о реализации CPython: Это адрес объекта в памяти.
ОК, поэтому вВообще, когда два имени указывают на один и тот же объект, они будут иметь один и тот же id()
.
Почему тогда у нас это есть?
str1 = 'aaa'
str2 = 'aaa'
print(id(str1) == id(str2)) # True
Это потому, что в CPython (эталонная реализация Python на C), строки кэшируются в хеш-таблице (по соображениям производительности), и дешевле иметь str1
и str2
для указания на одну и ту же память. Обратите внимание, что это можно сделать без особых неожиданных действий, поскольку строки в Python неизменны. Однако этот механизм запускается только для строк, которые полностью отображаются в интерпретаторе , например:
for i in range(5):
a = eval('"' + 'a' * i + '"')
b = eval('"' + 'a' * i + '"')
print(id(a) == id(b), a, b)
True
True a a
True aa aa
True aaa aaa
True aaaa aaaa
Любой механизм, создающий str
динамически в интерпретаторе (т. е. кроме eval()
), вне этого кэширования, как ваш пример, или:
a = 'aaa'
b = a[1:]
c = 'aa'
print(id(b) == id(c))
# False
print(id(b) == id(a[1:]))
# False
Для дальнейшего ознакомления внутреннее представление строк в Python описано более подробнодеталь в PEP 393 .