访问对象存储器地址
时间:2020-03-06 14:36:10 来源:igfitidea点击:
当我们在Python中调用object .__ repr __()方法时,我们会得到类似以下的信息:
<main.Test object at 0x2aba1c0cf890>
如果重载__repr __(),然后调用super(Class,obj).__ repr __()
并将其重新赋值,还有什么方法可以保留内存地址?
解决方案
只需使用
id(object)
我们可以通过以下方式获得适合该目的的东西:
id(self)
Python手册中有关于id()
的说法:
Return the ``identity'' of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value. (Implementation note: this is the address of the object.)
因此,在CPython中,这将是对象的地址。但是,对于任何其他Python解释器都没有这样的保证。
请注意,如果我们正在编写C扩展名,则可以完全访问Python解释器的内部,包括直接访问对象的地址。
我们可以通过以下方式重新实现默认的repr:
def __repr__(self): return '<%s.%s object at %s>' % ( self.__class__.__module__, self.__class__.__name__, hex(id(self)) )
使用ctypes,我们可以使用
>>> import ctypes >>> a = (1,2,3) >>> ctypes.addressof(a) 3077760748L
说明文件:
addressof(C instance) -> integer Return the address of the C instance internal buffer
注意在CPython中,当前id(a)== ctypes.addressof(a)
,但是ctypes.addressof
应该返回每个Python实现的真实地址,如果
- 支持ctypes
- 内存指针是一个有效的概念。
编辑:添加了有关ctypes解释器独立性的信息
虽然id(object)
在默认的CPython实现中获取对象的地址是正确的,但这通常是无用的……我们不能对纯Python代码中的地址做任何事情。
实际上,唯一可以使用该地址的时间是来自C扩展库...在这种情况下,获取对象的地址很简单,因为Python对象始终作为C指针传递。