thr*_*thr 154 python object repr memory-address
当您object.__repr__()在Python中调用该方法时,您会得到类似这样的内容:
Run Code Online (Sandbox Code Playgroud)<__main__.Test object at 0x2aba1c0cf890>
如果你超载__repr__(),有没有办法得到一个内存地址,除了调用super(Class, obj).__repr__()和重新出现之外?
Nic*_*son 188
在Python的手册已经这样说id():
返回一个对象的"identity".这是一个整数(或长整数),保证在该生命周期内该对象是唯一的和常量的.具有非重叠生存期的两个对象可能具有相同的id()值. (实施说明:这是对象的地址.)
所以在CPython中,这将是对象的地址.但是,对于任何其他Python解释器都没有这样的保证.
请注意,如果您正在编写C扩展,则可以完全访问Python解释器的内部,包括直接访问对象的地址.
Arm*_*her 64
你可以这样重新实现默认的repr:
def __repr__(self):
return '<%s.%s object at %s>' % (
self.__class__.__module__,
self.__class__.__name__,
hex(id(self))
)
Run Code Online (Sandbox Code Playgroud)
Ben*_*ein 47
只是用
id(object)
Run Code Online (Sandbox Code Playgroud)
aba*_*ert 22
这里有一些问题没有被任何其他答案所涵盖.
首先,id只返回:
对象的"身份".这是一个整数(或长整数),保证在该生命周期内该对象是唯一且恒定的.具有非重叠寿命的两个对象可以具有相同的
id()值.
在CPython中,这恰好是指向PyObject解释器中对象的指针,这与object.__repr__显示的内容相同.但这只是CPython的一个实现细节,而不是Python的一般情况.Jython的不处理的指针,它在Java中引用交易(当然的JVM可能代表为指针,但你不能看到那些和不希望的,因为GC是允许移动它们).PyPy允许不同类型具有不同类型id,但最常见的只是您调用的对象表的索引id,这显然不是指针.我不确定IronPython,但我怀疑它在这方面比Jython更像CPython.因此,在大多数Python实现中,没有办法得到任何显示的东西repr,如果你这样做就没有用.
但是如果你只关心CPython呢?毕竟,这是一个很常见的情况.
好吧,首先,你可能会注意到这id是一个整数;*如果你想要那个0x2aba1c0cf890字符串而不是数字46978822895760,你将不得不自己格式化它.在幕后,我相信object.__repr__最终会使用你没有Python printf的%p格式......但是你可以随时这样做:
format(id(spam), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')
Run Code Online (Sandbox Code Playgroud)
*在3.x中,它是一个int.在2.x中,int如果它足够大以容纳一个指针 - 这可能不是因为在某些平台上签名的数字问题 - 而是long另外一个.
除了打印出来之外,你能用这些指针做些什么吗?当然(再次假设你只关心CPython).
所有C API函数都使用指向PyObject或相关类型的指针.对于那些相关的类型,你可以调用PyFoo_Check以确保它确实是一个Foo对象,然后使用(PyFoo *)p.所以,如果您正在编写C扩展,那么id这正是您所需要的.
如果你正在编写纯Python代码怎么办?您可以使用pythonapifrom 调用完全相同的函数ctypes.
最后,提出了一些其他答案ctypes.addressof.这与此无关.这仅适用于ctypes像c_int32(和一些类似内存缓冲区的对象,如提供的对象numpy)这样的对象.而且,即使在那里,它是不是给你的地址c_int32值,它给你的C级的地址int32的c_int32包裹起来.
话虽如此,通常情况下,如果你真的认为你需要某些东西的地址,你首先想要一个原生的Python对象,你想要一个ctypes对象.
Pet*_*Bek 13
仅仅是为了回应Torsten,我无法调用addressof()常规的python对象.而且,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
Run Code Online (Sandbox Code Playgroud)
使用ctypes,您可以使用
>>> import ctypes
>>> a = (1,2,3)
>>> ctypes.addressof(a)
3077760748L
Run Code Online (Sandbox Code Playgroud)
说明文件:
addressof(C instance) -> integer
返回C实例内部缓冲区的地址
请注意,在CPython中,当前为id(a) == ctypes.addressof(a),但ctypes.addressof应返回每个Python实现的真实地址,如果
编辑:添加了有关ctypes解释器独立性的信息