是否可能在python中获得“地址值”?

问题描述 投票:0回答:2

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

>>> a=100
>>> id(a)
4304852448
>>> a+=5
>>> id(a)
4304852608

是否有办法查看(旧)内存地址4304852448(0x10096d5e0)的值是什么?例如:value_of(0x10096d5e0)

python cpython python-internals
2个回答
3
投票

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

否; 代表对象结果值不同的内存地址。通常,该对象是在运行时创建的,但是专门针对整数(不可变的,以及某些采用类似优化的其他类型),该对象可能已经存在并可以重用。

是否有办法查看(旧)内存地址4304852448(0x10096d5e0)的值是什么?

这个问题提出得不好。首先,在这种情况下,“内存地址”被虚拟化,可能不止一次。其次,在Python模型中,地址没有“具有值”。它们可能是对象的位置,它们依次表示值。

表示:在前一个id(a)的位置上,当且仅当未进行垃圾收集时,旧对象仍将存在。为此,对对象保持一些其他引用就足够了。 (垃圾收集的时间由实现定义,但是参考CPython实现通过引用计数实现垃圾收集。)

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

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

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


3
投票

您正在尝试取消引用内存地址,就像在C / C ++中使用的指针一样。以下代码可能会对您有所帮助-

import ctypes

a = 100
b = id(a)

print(b, ": ", a)

a+=5
print(id(a), ": ", a)

print(ctypes.cast(b, ctypes.py_object).value)

输出:

140489243334080 :  100
140489243334240 :  105
100

以上示例确定存储在a的先前地址中的值保持不变。

希望这能回答问题。阅读@Karl的答案,以了解有关后台发生的情况的更多信息-https://stackoverflow.com/a/58468810/2650341

© www.soinside.com 2019 - 2024. All rights reserved.