可以在python中获得“地址值”吗?

Dav*_*542 0 python cpython python-internals

在下面,我可以看到在 python 中添加一个整数时,它添加了整数,将该结果值分配给一个新的内存地址,然后将变量设置为指向该内存地址:

>>> a=100
>>> id(a)
4304852448
>>> a+=5
>>> id(a)
4304852608
Run Code Online (Sandbox Code Playgroud)

有没有办法查看(旧)内存地址 4304852448 (0x10096d5e0) 处的值是多少?例如:value_of(0x10096d5e0)

Kar*_*tel 5

它添加整数,将该结果值分配给新的内存地址

不; 表示结果值的对象具有不同的内存地址。通常,这个对象是动态创建的,但特别是对于整数(不可变的,以及应用类似优化的其他一些类型),该对象可能已经存在并被重用。

有没有办法查看(旧)内存地址 4304852448 (0x10096d5e0) 处的值是多少?

这个问题不好提出。首先,此上下文中的“内存地址”被虚拟化,可能不止一次。其次,在 Python 模型中,地址没有“值”。它们可能是对象的位置,而对象又代表值。

也就是说:在前一个的位置,id(a)当且仅当它没有被垃圾收集时,旧对象仍然存在。为此,对对象持有一些其他引用就足够了。(垃圾收集的时间是实现定义的,但参考 CPython 实现通过引用计数实现垃圾收集。)

通常,您无权直接检查底层内存(除非使用某种具有适当权限的进程间谍),因为 Python 并不是那么低级的语言。(在@xprilion 的回答中,CPython 实现通过 提供了一个较低级别的内存接口ctypes;但是,那里的代码实际上是在进行不安全的转换。)

如果您这样做了(并假设使用 CPython),您将不会在第一次100调用id(a)所指示的内存位置中看到整数的二进制表示- 您会看到PyObject用于在 C 代码中实现对象的结构的第一个字,它(如果我读正确)将是一个指针指向下一个现场堆对象(所有连接在一个双向链表)。

一旦它被垃圾收集,该内存的内容将再次未定义。它们取决于实现,甚至特别是对于 C 实现,它们取决于标准库 free() 对内存的处理方式。(通常它会保持不变,因为没有理由将它清零并且这样做需要时间。调试版本可能会将特殊值写入该内存,因为它有助于检测内存损坏。)