通过 id() 获取对象?[重复]
- 2024-12-24 08:56:00
- admin 原创
- 92
问题描述:
假设我有一个 Python 对象的 id,我通过执行 检索了它。如何通过我给出的 id 号再次id(thing)
找到它?thing
解决方案 1:
如果物体仍然存在,可以这样做ctypes
:
import ctypes
a = "hello world"
print ctypes.cast(id(a), ctypes.py_object).value
输出:
hello world
如果您不知道该对象是否仍然在那里,这可能会导致未定义的行为和奇怪的崩溃或更糟糕的情况,所以要小心。
解决方案 2:
您可能想考虑以另一种方式实现它。您知道weakref模块吗?
(已编辑)Python弱引用模块允许您保留对对象的引用、字典引用和代理,而无需将这些引用计入引用计数器中。它们就像符号链接一样。
解决方案 3:
您可以使用gc模块获取 Python 垃圾收集器当前跟踪的所有对象。
import gc
def objects_by_id(id_):
for obj in gc.get_objects():
if id(obj) == id_:
return obj
raise Exception("No found")
解决方案 4:
简而言之,你不能。
长答案,你可以维护一个字典来将ID映射到对象,或者通过穷举搜索来查找ID gc.get_objects()
,但这会产生两个问题之一:要么字典的引用将保持对象活动并阻止GC,或者(如果它是一个WeakValue字典或你使用gc.get_objects()
)ID可能会被释放并重新用于完全不同的对象。
基本上,如果您尝试这样做,您可能需要做一些不同的事情。
解决方案 5:
仅提及此模块以说明完整性。Bill Bumgarner 编写的此代码包含一个 C 扩展,可执行您想要的操作,而无需循环遍历现有的每个对象。
该函数的代码非常简单。每个 Python 对象在 C 中都由指向 struct 的指针表示。PyObject
由于只是id(x)
此结构的内存地址,因此我们只需将其视为x
指向 的指针即可检索 Python 对象PyObject
,然后调用Py_INCREF
来告诉垃圾收集器我们正在创建对该对象的新引用。
static PyObject *
di_di(PyObject *self, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "l:di", &obj))
return NULL;
Py_INCREF(obj);
return obj;
}
如果原始对象不再存在,则结果未定义。它可能会崩溃,但也可能返回对新对象的引用,该新对象在内存中占据了旧对象的位置。
解决方案 6:
eGenix mxTools 库确实提供了这样的功能,尽管标记为“仅限专家”:mx.Tools.makeref(id)
解决方案 7:
这将做到:
a = 0
id_a = id(a)
variables = {**locals(), **globals()}
for var in variables:
exec('var_id=id(%s)'%var)
if var_id == id_a:
exec('the_variable=%s'%var)
print(the_variable)
print(id(the_variable))
但我建议实施一种更得体的方式。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)