객체 메모리 주소에 액세스합니다
-
02-07-2019 - |
문제
당신이 전화 할 때 object.__repr__()
파이썬에서 방법으로 이와 같은 것을 얻을 수 있습니다.
<__main__.Test object at 0x2aba1c0cf890>
과부하가 발생하면 메모리 주소를 잡을 수있는 방법이 있습니까? __repr__()
, 다른 전화 super(Class, obj).__repr__()
그리고 그것을 다시 배제합니까?
해결책
그만큼 파이썬 매뉴얼 이것에 대해 말할 수 있습니다 id()
:
물체의 "Identity ''를 반환하십시오. 이것은 수명 동안이 객체에 대해 독특하고 일정하게 보장되는 정수 (또는 긴 정수)입니다. 겹치지 않는 수명이있는 두 개의 객체는 동일한 ID () 값을 가질 수 있습니다. (구현 참고 : 이것은 객체의 주소입니다.)
따라서 Cpython에서는 이것이 객체의 주소가 될 것입니다. 그러나 다른 Python 통역사에게는 그러한 보장이 없습니다.
C 확장을 작성하는 경우 Python 통역사의 내부에 직접 액세스 할 수 있습니다.
다른 팁
이 방법으로 기본 정보를 다시 구현할 수 있습니다.
def __repr__(self):
return '<%s.%s object at %s>' % (
self.__class__.__module__,
self.__class__.__name__,
hex(id(self))
)
그냥 사용하십시오
id(object)
여기에는 다른 답변이 다루지 않는 몇 가지 문제가 있습니다.
첫 번째, id
반품 만 :
대상의“정체성”. 이것은 정수 (또는 긴 정수)로, 수명 동안이 객체에 대해 독특하고 일정하게 보장됩니다. 겹치지 않는 수명이없는 두 개의 물체는 동일 할 수 있습니다
id()
값.
Cpython에서 이것은 PyObject
그것은 통역사의 객체를 나타냅니다. object.__repr__
디스플레이. 그러나 이것은 일반적으로 Python의 사실이 아니라 Cpython의 구현 세부 사항 일뿐입니다. Jython은 Pointers를 다루지 않고 Java 참조를 다루고 있습니다 (물론 JVM은 아마도 포인터로 나타나지 만 GC가 그것들을 움직일 수 있기 때문에 그것을 볼 수는 없지만 원하지 않을 것입니다). Pypy는 다른 유형의 다른 종류를 가질 수있게합니다 id
, 그러나 가장 일반적인 것은 당신이 불렀던 물체 테이블에 대한 색인 일뿐입니다. id
켜기, 그것은 분명히 포인터가되지 않을 것입니다. 나는 Ironpython에 대해 잘 모르겠지만, 이와 관련하여 Cpython보다 Jython과 비슷하다고 생각합니다. 따라서 대부분의 파이썬 구현에서 repr
, 그리고 당신이 그렇게한다면 사용하지 않습니다.
그러나 Cpython에만 관심이 있다면 어떨까요? 결국 그것은 꽤 일반적인 경우입니다.
글쎄, 먼저, 당신은 그것을 알 수 있습니다 id
정수입니다.* 원한다면 0x2aba1c0cf890
숫자 대신 문자열 46978822895760
, 당신은 직접 포맷해야 할 것입니다. 덮개 아래, 나는 믿는다 object.__repr__
궁극적으로 사용 중입니다 printf
'에스 %p
파이썬에서 가지고 있지 않은 형식… 그러나 항상 이것을 할 수 있습니다.
format(id(spam), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')
* 3.x에서는입니다 int
. 2.X에서는입니다 int
그것이 포인터를 보유하기에 충분히 큰 경우 - 일부 플랫폼에서 서명 된 번호 문제로 인해 발생하지 않을 수 있습니다. long
그렇지 않으면.
인쇄 외에이 포인터로 할 수있는 일이 있습니까? 물론 (다시, Cpython에만 관심이 있다고 가정).
모든 C API 함수는 a에 대한 포인터를 취합니다 PyObject
또는 관련 유형. 이러한 관련 유형의 경우 전화 할 수 있습니다 PyFoo_Check
그것이 실제로 무엇인지 확인하기 위해 Foo
객체, 그 다음 캐스트 (PyFoo *)p
. 따라서 C 확장을 작성하는 경우 id
정확히 필요한 것입니다.
순수한 파이썬 코드를 작성하는 경우 어떻게해야합니까? 정확히 동일한 기능을 호출 할 수 있습니다 pythonapi
~에서 ctypes
.
마지막으로, 다른 답변 중 일부는 ctypes.addressof
. 여기에는 관련이 없습니다. 이것은 만 작동합니다 ctypes
같은 개체 c_int32
(그리고 아마 numpy
). 그리고 거기에서도 그것은 당신에게 c_int32
가치, 그것은 당신에게 c 레벨의 주소를 제공합니다. int32
그 c_int32
마무리.
즉, 더 자주 말하지만, 당신이 정말로 무언가의 주소가 필요하다고 생각한다면, 당신은 처음에 기본 Python 객체를 원하지 않았고, 당신은 원했습니다. ctypes
물체.
Torsten에 대한 응답으로 전화를 걸 수 없었습니다. addressof()
일반 파이썬 객체에. 뿐만 아니라, id(a) != addressof(a)
. 이것은 Cpython에 있습니다. 다른 것에 대해 알지 못합니다.
>>> from ctypes import c_int, addressof
>>> a = 69
>>> addressof(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: invalid type
>>> b = c_int(69)
>>> addressof(b)
4300673472
>>> id(b)
4300673392
와 함께 ctypes, 당신은 같은 것을 달성 할 수 있습니다
>>> import ctypes
>>> a = (1,2,3)
>>> ctypes.addressof(a)
3077760748L
선적 서류 비치:
addressof(C instance) -> integer
C 인스턴스 내부 버퍼의 주소를 반환합니다
Cpython에서는 현재입니다 id(a) == ctypes.addressof(a)
, 하지만 ctypes.addressof
각 파이썬 구현에 대한 실제 주소를 반환해야합니다.
- CTYPES가 지원됩니다
- 메모리 포인터는 유효한 개념입니다.
편집하다: CTYPES의 통역 독립성에 대한 정보가 추가되었습니다
다음과 같이 그 목적에 적합한 것을 얻을 수 있습니다.
id(self)
그것이 사실이지만 id(object)
기본 CPYTHON 구현에서 객체의 주소를 가져옵니다. 이것은 일반적으로 쓸모가 없습니다 ... 당신은 할 수 없습니다. 하다 순수한 파이썬 코드의 주소가있는 모든 것.
실제로 주소를 사용할 수있는 유일한 시간은 C Extension 라이브러리에서 나온 것입니다.이 경우 Python 객체가 항상 C 포인터로 전달되기 때문에 객체 주소를 얻는 것이 중요합니다.