Python 访问对象内存地址

Python 访问对象内存地址,python,object,memory-address,repr,Python,Object,Memory Address,Repr,在Python中调用对象.\uuuu repr\uuuu()方法时,会得到如下结果: 如果你重载\uuu repr\uuu(),除了调用super(Class,obj).\uu repr\uu()并将其重新设置外,还有什么方法可以获得内存地址 只要使用 id(object) 您可以通过以下方式获得适合该目的的产品: id(self) 这是关于id()的: 返回对象的“标识”。 这是一个整数(或长整数) 它保证是独一无二的,并且 此对象在运行期间的常数 生命周期。两个具有 非重叠生命周期可

在Python中调用
对象.\uuuu repr\uuuu()
方法时,会得到如下结果:


如果你重载
\uuu repr\uuu()
,除了调用
super(Class,obj).\uu repr\uu()
并将其重新设置外,还有什么方法可以获得内存地址

只要使用

id(object)

您可以通过以下方式获得适合该目的的产品:

id(self)
这是关于
id()
的:

返回对象的“标识”。 这是一个整数(或长整数) 它保证是独一无二的,并且 此对象在运行期间的常数 生命周期。两个具有 非重叠生命周期可能具有 相同的id()值。(实现说明: 这是对象的地址。)

因此,在CPython中,这将是对象的地址。不过,对于任何其他Python解释器,都不能保证这一点


请注意,如果您正在编写C扩展,您可以完全访问Python解释器的内部,包括直接访问对象的地址。

您可以通过以下方式重新实现默认的repr:

def __repr__(self):
    return '<%s.%s object at %s>' % (
        self.__class__.__module__,
        self.__class__.__name__,
        hex(id(self))
    )
def\uuu repr\uu(自):
返回“”%(
自我。类。模块,
self.\uuuuu类\uuuuuuu名\uuuuuuuuu,
十六进制(id(自身))
)
使用,您可以通过

>>> import ctypes
>>> a = (1,2,3)
>>> ctypes.addressof(a)
3077760748L
文件:

addressof(C实例)->integer

返回C实例内部缓冲区的地址

注意,在CPython中,当前
id(a)=ctypes.addressof(a)
,但是
ctypes.addressof
应该返回每个Python实现的实际地址,如果

  • 支持ctypes
  • 内存指针是一个有效的概念

Edit:添加了关于ctypes的解释器独立性的信息

虽然
id(object)
确实在默认的CPython实现中获取了对象的地址,但这通常是没有用的……纯Python代码中的地址无法使用


实际上,您唯一能够使用地址的时间是从C扩展库……在这种情况下,获取对象的地址很简单,因为Python对象总是作为C指针传递。

只是为了响应Torsten,我无法在常规Python对象上调用
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导入c_int,addressof
>>>a=69
>>>地址(a)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:无效的类型
>>>b=c_int(69)
>>>地址(b)
4300673472
>>>身份证(b)
4300673392

这里有一些问题在其他任何答案中都没有涉及

首先,只有返回:

对象的“标识”。这是一个整数(或长整数),保证该对象在其生存期内唯一且不变。具有非重叠生存期的两个对象可能具有相同的
id()


在CPython中,这恰好是指向表示解释器中对象的指针,它与
对象显示的内容相同。但这只是CPython的一个实现细节,而不是Python的一般情况。Jython不处理指针,它处理Java引用(JVM当然可能表示为指针,但您看不到这些指针,也不想看到它们,因为允许GC移动它们).PyPy允许不同类型具有不同类型的
id
,但最通用的方法只是对您调用的
id
对象表的索引,这显然不是指针。我不确定IronPython,但我怀疑它在这方面更像Jython,而不是CPython。因此,在大多数Python实现中,没有办法获得该
repr
中显示的内容,如果您这样做了,也没有用


但如果你只关心CPython呢?毕竟这是一个很常见的情况

首先,你可能会注意到,
id
是一个整数;*如果你想要
0x2aba1c0cf890
字符串而不是数字
46978822895760
,你必须自己格式化它。在封面下,我相信
对象。u repr\uuu
最终使用的是
printf
%p
格式,你可以使用它在上,我们没有Python的功能…但您始终可以这样做:

format(id(spam), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')

format(id(spam),“#010x”if sys.maxsize.bit_length()我知道这是一个老问题,但如果你现在还在用python 3编程……我发现如果它是一个字符串,那么有一个非常简单的方法可以做到这一点:

>>> spam.upper
<built-in method upper of str object at 0x1042e4830>
>>> spam.upper()
'YO I NEED HELP!'
>>> id(spam)
4365109296
>>spam.upper
>>>spam.upper()
“哟,我需要帮助!”
>>>id(垃圾邮件)
4365109296
字符串转换也不会影响内存中的位置:

>>> spam = {437 : 'passphrase'}
>>> object.__repr__(spam)
'<dict object at 0x1043313f0>'
>>> str(spam)
"{437: 'passphrase'}"
>>> object.__repr__(spam)
'<dict object at 0x1043313f0>'
>垃圾邮件={437:'passphrase'}
>>>对象。\uuuu repr\uuuuu(垃圾邮件)
''
>>>str(垃圾邮件)
“{437:'密码短语'}”
>>>对象。\uuuu repr\uuuuu(垃圾邮件)
''

>>导入ctypes>>>a=(1,2,3)>>>ctypes.addressof(a)回溯(最近一次调用):文件“”,第1行,类型错误:无效类型>>>id(a)4493268872>>>我同意Barry的观点:当我用Python 3.4尝试时,上面的代码会导致
TypeError:invalid type
。除非您使用标准库中内置的
ctypes
工具包。在这种情况下,您可以使用地址做各种事情:)这不是对这个问题的一个通用答案;它只适用于CPython。请赛尔夫注意:该保证不适用于多处理某些使用它的方法(比较它包含的值):对象的
生存期是什么(以及
重叠/不重叠
对生存期意味着什么)在此上下文中是否引用?@MinhTran,因为id是对象的内存地址,因此保证它在进程中是唯一的,并且当对象存在时。在对象被垃圾回收后的一段时间内,内存可以重新使用。非重叠PIN
>>> spam = {437 : 'passphrase'}
>>> object.__repr__(spam)
'<dict object at 0x1043313f0>'
>>> str(spam)
"{437: 'passphrase'}"
>>> object.__repr__(spam)
'<dict object at 0x1043313f0>'