You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python 3中通过对象地址操作对象成员数据?

通过对象地址访问并操作Python对象的成员数据

你提到的需求完全可以通过ctypes实现——这正是用来和底层内存交互、对接C语言逻辑的工具。之前你尝试用string_at读取内存字节,只能拿到原始数据,而要真正获取可操作的Python对象,核心是用ctypes.cast()把内存地址转换成Python对象类型。

核心实现步骤

  1. 把十六进制格式的地址字符串转回整数(因为hex(id(obj))只是把整数地址转成了可读性更高的十六进制字符串,而ctypes需要整数形式的地址)
  2. 用ctypes.cast()将地址转换为py_object类型,再通过.value拿到原始对象的引用
  3. 之后就可以像操作普通对象一样访问、修改它的成员了

针对你的TestObject示例的完整代码

import ctypes

class TestObject:
    myMemberData = 5

# 创建对象并获取地址
obj = TestObject()
address = hex(id(obj))
print(f"对象地址: {address}")

# 反向恢复对象
addr_integer = int(address, 16)
# 把地址转换成Python对象引用
recovered_obj = ctypes.cast(addr_integer, ctypes.py_object).value

# 验证并修改成员
print(f"原始对象的成员值: {obj.myMemberData}")
print(f"从地址恢复的对象成员值: {recovered_obj.myMemberData}")

# 修改恢复对象的成员,原对象会同步变化(因为指向的是同一个内存对象)
recovered_obj.myMemberData = 6
print(f"修改后原始对象的成员值: {obj.myMemberData}")

运行这段代码会输出类似:

对象地址: 0x7f8b1c0b3d30
原始对象的成员值: 5
从地址恢复的对象成员值: 5
修改后原始对象的成员值: 6

为什么之前的string_at无法解决问题?

string_at只是读取指定地址开始的一段内存字节,返回的是原始字节串,它不会帮你把这些字节解析成Python对象。你看到的字节变化只是底层内存的原始结构(比如小整数的缓存数据),但无法直接通过这些字节操作对象的成员。而ctypes.cast()会明确告诉Python:"这个地址对应的是一个Python对象,请把它转换成我能直接操作的对象引用"——这才是实现需求的关键步骤。

重要注意事项

  • 垃圾回收风险:必须确保你操作的地址对应的对象还没有被Python的垃圾回收机制回收。如果对象已经被回收,这个地址可能已经被其他数据占用,操作会导致程序崩溃或者不可预期的行为。
  • 平台/版本兼容性:Python的对象内存布局在不同版本(比如3.8和3.11)、不同操作系统(Windows/Linux/macOS)之间可能有差异,这种方法属于底层hack,不保证跨环境通用。
  • 仅用于特殊场景:这种操作绕过了Python的内存安全模型,正常业务代码绝对不要使用,一般只用于调试、逆向工程或者非常特殊的底层需求。

内容的提问来源于stack exchange,提问作者O'Niel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:53:59