В руководстве по Python сказано следующее id()
:
Возвращает «идентификатор» объекта. Это целое число (или длинное целое число), которое гарантированно будет уникальным и постоянным для этого объекта в течение его времени жизни. Два объекта с непересекающимися временами жизни могут иметь одинаковое значение id (). (Примечание по реализации: это адрес объекта.)
Так что в CPython это будет адрес объекта. Однако нет никакой гарантии для любого другого интерпретатора Python.
Обратите внимание, что если вы пишете расширение C, у вас есть полный доступ к внутренним компонентам интерпретатора Python, включая прямой доступ к адресам объектов.
lifetime
(и что это означает для жизниoverlap/not overlap
) в этом контексте?Вы можете переопределить repr по умолчанию следующим образом:
источник
return object.__repr__(self)
или даже делать,object.__repr__(obj)
когда вам это нужно, вместо того, чтобы создавать новый класс__repr__ = object.__repr__
, и он не так уж и дурак, поскольку есть множество ситуаций, когда это не работает, например, переопределенная__getattribute__
или не-CPython реализация, где идентификатор не является идентификатором. место в памяти. Это также не z-заполнение, поэтому вам придется работать, если система является 64-битной и добавлять нули по мере необходимости.Просто используйте
источник
id()
@JLTЗдесь есть несколько вопросов, которые не охвачены другими ответами.
Во-первых,
id
только возвращается:В CPython это указатель на on, который явно не будет указателем. Я не уверен насчет IronPython, но я подозреваю, что в этом отношении он больше похож на Jython, чем на CPython. Таким образом, в большинстве реализаций Python нет способа получить что-либо, показанное в этом , и бесполезно, если вы это сделали.
PyObject
на объект, представляющий объект в интерпретаторе, которыйobject.__repr__
отображает то же самое . Но это всего лишь деталь реализации CPython, а не то, что верно для Python в целом. Jython не имеет дело с указателями, он имеет дело с ссылками на Java (которые, конечно, JVM, вероятно, представляет в виде указателей, но вы не можете видеть их - и не захотите, потому что GC разрешено перемещать их). PyPy позволяет разным типам иметь разные видыid
, но самый общий - это просто индекс в таблицу объектов, которые вы назвалиid
repr
Но что, если вы заботитесь только о CPython? В конце концов, это довольно распространенный случай.
Ну, во-первых, вы можете заметить, что
id
это целое число; * если вы хотите эту0x2aba1c0cf890
строку вместо числа46978822895760
, вам придется форматировать ее самостоятельно. Под одеялом, я считаюobject.__repr__
, в конечном счете , используяprintf
«s%p
формат, который вы не имеете с Python ... но вы всегда можете сделать это:* В 3.x это
int
. В 2.x этоint
достаточно большой размер, чтобы удерживать указатель, что может быть не так из-за проблем со знаком на некоторых платформах, иlong
другое.Можно ли что-нибудь сделать с этими указателями, кроме как распечатать их? Конечно (опять же, если вы заботитесь только о CPython).
Все функции C API получают указатель на
PyObject
или связанный тип. Для этих связанных типов, вы можете просто вызвать,PyFoo_Check
чтобы убедиться, что это действительноFoo
объект, а затем привести с помощью(PyFoo *)p
. Итак, если вы пишете расширение C, тоid
это именно то, что вам нужно.Что если вы пишете чистый код на Python? Вы можете вызвать ту же функцию , с
pythonapi
изctypes
.Наконец, несколько других ответов были подняты
ctypes.addressof
. Это не актуально здесь. Это работает только дляctypes
таких объектов, какc_int32
(и, может быть, несколько объектов, подобных буферу памяти, как те, которые предоставляютсяnumpy
). И даже там, он не дает вам адресc_int32
значения, он дает вам адрес уровня C,int32
которыйc_int32
завершает.Это, как говорится, чаще всего, если вы действительно думаете, что вам нужен адрес чего-то, вы изначально не хотели нативный объект Python, вы хотели
ctypes
объект.источник
id
числе использование их для хранения изменяемых значений вseen
наборе илиcache
dict - никак не зависит от того,id
является ли указатель или каким-либо образом связано сrepr
. Именно поэтому такой код работает во всех реализациях Python, а не только в CPython.id
для этого, но я имею в виду, что даже в java вы можете получить адрес объекта, кажется странным, что в (C) Python нет пути, так как у него действительно стабильный gc, который не будет перемещать объекты, поэтому адрес остается прежнимid
, независимо от того, является ли он адресом или нет. Например, в PyPyid
он по-прежнему так же полезен, как и ключ в CPython, хотя обычно это просто указатель на какую-то скрытую таблицу в реализации, но указатель будет бесполезен, поскольку (как и в Java) объект может быть перемещен в объем памяти.id
объект является указателем на местоположение объекта в памяти. Итак, если у вас есть какое-либо использование для значения указателя (что вы почти никогда не делаете, как также объясняется в ответе) в специфичном для CPython коде, есть способ получить его, который задокументирован и гарантированно будет работать.Просто в ответ на Торстена я не смог вызвать
addressof()
обычный объект python. Кроме того,id(a) != addressof(a)
. Это в CPython, больше ничего не знаю.источник
С помощью ctypes вы можете добиться того же
Документация:
Обратите внимание, что в CPython, в настоящее время
id(a) == ctypes.addressof(a)
, ноctypes.addressof
должен возвращать реальный адрес для каждой реализации Python, еслиРедактировать : добавлена информация о независимости интерпретатора ctypes
источник
TypeError: invalid type
что я пробую его с Python 3.4.Вы можете получить что-то подходящее для этой цели с:
источник
Я знаю, что это старый вопрос, но если вы все еще программируете, в Python 3 в эти дни ... Я действительно обнаружил, что если это строка, то есть действительно простой способ сделать это:
Преобразование строк также не влияет на расположение в памяти:
источник
Хотя это правда, что
id(object)
получает адрес объекта в реализации CPython по умолчанию, это, как правило, бесполезно ... вы не можете ничего сделать с адресом из чистого кода Python.Единственный раз, когда вы действительно сможете использовать адрес, это из библиотеки расширений C ... в этом случае получить адрес объекта тривиально, поскольку объекты Python всегда передаются как указатели C.
источник
ctypes
инструментарий в стандартной библиотеке. В этом случае вы можете делать все что угодно с адресом :)