当你在Python中调用object.__repr__()方法时,你会得到类似这样的结果:

< __main__。测试对象位于0x2aba1c0cf890>

如果你重载__repr__(),除了调用super(Class, obj).__repr__()和reexing它,有没有任何方法来获得内存地址?


当前回答

只是为了响应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

其他回答

你可以使用内置的'str'类型的'partition'方法获取任何对象的内存地址/位置。

下面是一个使用它来获取对象内存地址的例子:

Python 3.8.3 (default, May 27 2020, 02:08:17)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> object.__repr__(1)
'<int object at 0x7ca70923f0>'
>>> hex(int(object.__repr__(1).partition('object at ')[2].strip('>'), 16))
0x7ca70923f0
>>>

在这里,我使用内置的“对象”类“__repr__”方法与一个对象/项目如1作为参数返回字符串的字符串,然后我分区将返回一个元组的字符串之前我提供的字符串,我提供的字符串,然后我提供的字符串在字符串,以及内存位置定位后的物体”,我能得到它分区的内存地址的部分。

然后,由于内存地址作为返回元组中的第三项返回,我可以用索引2从元组中访问它。但是,它在我获得的字符串中有一个直角括号作为后缀,所以我使用'strip'函数来删除它,这将返回不带尖括号的字符串。然后,我将结果字符串转换为以16为基数的整数,然后将其转换为十六进制数。

如果__repr__重载,你可以考虑__str__来查看变量的内存地址。

下面是Moshe Zadka在StackOverflow中__repr__和__str__的细节。

你可以这样重新实现默认的repr:

def __repr__(self):
    return '<%s.%s object at %s>' % (
        self.__class__.__module__,
        self.__class__.__name__,
        hex(id(self))
    )

Python手册对id()是这样说的:

返回一个对象的“标识”。 这是一个整数(或长整数) 哪个保证是唯一的 常量 一生。两个对象 不重叠的生命周期可能有 相同的id()值。(注:实现 这是对象的地址。)

在CPython中,这是对象的地址。不过,其他任何Python解释器都没有这样的保证。

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

我知道这是一个老问题,但如果你现在还在用python 3编程……我实际上发现,如果它是一个字符串,那么有一个非常简单的方法来做到这一点:

>>> spam.upper
<built-in method upper of str object at 0x1042e4830>
>>> spam.upper()
'YO I NEED HELP!'
>>> id(spam)
4365109296

字符串转换也不影响内存中的位置:

>>> spam = {437 : 'passphrase'}
>>> object.__repr__(spam)
'<dict object at 0x1043313f0>'
>>> str(spam)
"{437: 'passphrase'}"
>>> object.__repr__(spam)
'<dict object at 0x1043313f0>'