当你打电话的 object.__repr__() 方法在Python你得到这样的事情回:

<__main__.Test object at 0x2aba1c0cf890> 

是否有任何方法得到保持存储地址如果你超载 __repr__(), 其他然后叫 super(Class, obj).__repr__() 和regexing出来吗?

有帮助吗?

解决方案

Python手册 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))
    )

只需使用

id(object)

这里有一些问题没有被其他任何答案所涵盖。

首先, id 仅返回:

  

&#8220;身份&#8221;一个对象。这是一个整数(或长整数),保证在该生命周期内该对象是唯一且恒定的。具有非重叠生存期的两个对象可能具有相同的 id()值。


在CPython中,这恰好是指向 PyObject <的指针/ code> 表示解释器中的对象,与 object .__ repr __ 显示的内容相同。但这只是CPython的一个实现细节,而不是Python的一般情况。 Jython不处理指针,它处理Java引用(JVM当然可能代表指针,但你不能看到那些&#8212;并且不希望,因为GC被允许移动它们)。 PyPy允许不同类型具有不同类型的 id ,但最常见的只是对您调用 id 的对象表的索引,这显然不会是一个指针。我不确定IronPython,但我怀疑它在这方面比Jython更像CPython。因此,在大多数Python实现中,没有办法获得 repr 中出现的任何内容,如果你这样做就没有用。


但是如果你只关心CPython怎么办?毕竟,这是一个很常见的情况。

嗯,首先,您可能会注意到 id 是一个整数; *如果您想要 0x2aba1c0cf890 字符串而不是数字 46978822895760 ,你将不得不自己格式化。在幕后,我相信 object .__ repr __ 最终使用的是 printf %p 格式,这是Python和#8230所没有的。 ;但你总是可以这样做:

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

*在3.x中,它是 int 。在2.x中,它是一个 int ,如果它足以容纳一个指针&#8212;这可能不是因为某些平台上的签名号码问题&#8212;以及 long 否则。

除了打印出来之外,你能用这些指针做些什么吗?当然(再说一次,假设你只关心CPython)。

所有 C API 函数都指向<代码> PyObject 或相关类型。对于那些相关类型,您只需调用 PyFoo_Check 以确保它确实是 Foo 对象,然后使用(PyFoo *)p 进行转换。因此,如果您正在编写C扩展名, id 正是您所需要的。

如果您正在编写纯Python代码,该怎么办?您可以使用 调用完全相同的函数来自 ctypes 的pythonapi


最后,其他一些答案提出了 ctypes.addressof 。这与此无关。这仅适用于 ctypes 对象,如 c_int32 (可能还有一些类似于内存缓冲区的对象,如 numpy 提供的对象)。而且,即使在那里,也没有给你 c_int32 的地址,它给你的是 c_int32 <的C级 int32 的地址/ code>结束。

话虽如此,通常情况下,如果你真的认为你需要某些东西的地址,你首先不需要原生的Python对象,你需要一个 ctypes 对象。

为了回应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, 你可以实现同样的事情

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

文件:

addressof(C instance) -> integer
返回的地址C内部缓冲区的实例

请注意,在CPython,目前 id(a) == ctypes.addressof(a), 但 ctypes.addressof 应该回实地址的每个Python执行情况,如果

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

编辑:添加的信息有关解释的独立的ctypes

您可以通过以下方式获得适合此目的的内容:

id(self)

虽然 id(object)确实在默认的CPython实现中获取了对象的地址,但这通常是无用的...你不能任何事情来自纯Python代码的地址。

实际能够使用该地址的唯一时间来自C扩展库...在这种情况下,获取对象的地址是微不足道的,因为Python对象总是作为C指针传递。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top