通过id()获取对象?

比方说,我有一个Python对象的ID,我通过做id(thing)检索。 我如何通过我给的身份证号码再次找到thing

你可能会考虑以另一种方式来实现它。 你知道weakref模块吗?

(已编辑)Python weakref模块允许您将引用,字典引用和代理保留给对象,而不必在引用计数器中计算这些引用。 他们就像符号链接。

如果对象仍然存在,可以通过ctypes完成:

 import ctypes a = "hello world" print ctypes.cast(id(a), ctypes.py_object).value 

输出:

 hello world 

如果你不知道对象是否仍然存在,这是一个不确定的行为和怪异的崩溃或更糟的配方,所以要小心。

简短的回答,你不能。

很长的答案,你可以维护一个字典ID映射到对象,或通过穷举搜索gc.get_objects()查找ID,但这会产生两个问题之一:字典的引用将保持对象的活着,并防止GC ,或者(如果它是一个WeakValue字典或者你使用了gc.get_objects() ),这个ID可能会被释放并被重新用于一个完全不同的对象。

基本上,如果你正在试图做到这一点,你可能需要做一些不同的事情。

您可以使用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") 

只是提到这个模块的完整性。 Bill Bumgarner编写的这段代码包含一个C扩展,可以在不存在每个对象的情况下循环执行所需的操作。

该函数的代码非常简单。 每个Python对象都由一个指向PyObject结构的指针来表示 。 因为id(x)只是这个结构体的内存地址,所以我们可以通过把x当作指向PyObject的指针来获取Python对象,然后调用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; } 

如果原始对象不再存在,则结果是未定义的。 它可能会崩溃,但它也可能返回一个新的对象的引用,这个新的对象是旧内存中的位置。

eGenix mxTools库确实提供了这样的功能,虽然标记为“expert-only”: mx.Tools.makeref(id)

这将做到:

 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)) 

但我建议实施一个更体面的方式。