Obtener objeto por id ()?

Digamos que tengo una ID de un objeto Python, que recuperé haciendo id(thing) . ¿Cómo encuentro otra thing por el número de identificación que me dieron?

Probablemente querrás considerar implementarlo de otra manera. ¿Es usted consciente del módulo débil?

(Editado) El módulo weakref de Python le permite mantener referencias, referencias de diccionarios y proxies a objetos sin tener esas referencias en el contador de referencias. Son como enlaces simbólicos.

Si el objeto todavía está allí, esto se puede hacer mediante ctypes :

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

salida:

 hello world 

Si no sabe si el objeto todavía está allí, esta es una receta para un comportamiento indefinido y fallas extrañas o algo peor, así que tenga cuidado.

Respuesta corta, no puedes.

Respuesta larga, puede mantener un dict para asignar identificaciones a objetos, o buscar la identificación mediante una búsqueda exhaustiva de gc.get_objects() , pero esto creará uno de dos problemas: la referencia del dict mantendrá el objeto vivo y evitará que GC , o (si es un dict de WeakValue o si usa gc.get_objects() ), la ID puede ser desasignada y reutilizada para un objeto completamente diferente.

Básicamente, si estás tratando de hacer esto, es probable que necesites hacer algo diferente.

Puede usar el módulo gc para obtener todos los objetos actualmente rastreados por el recolector de basura de Python.

 import gc def objects_by_id(id_): for obj in gc.get_objects(): if id(obj) == id_: return obj raise Exception("No found") 

Solo mencionando este módulo para completar. Este código de Bill Bumgarner incluye una extensión C para hacer lo que quieras sin hacer un bucle en todos los objetos existentes.

El código para la función es bastante sencillo. Cada objeto de Python está representado en C por un puntero a una estructura PyObject . Debido a que id(x) es solo la dirección de memoria de esta estructura, podemos recuperar el objeto Python simplemente tratando x como un puntero a un PyObject , y luego llamar a Py_INCREF para decirle al recolector de basura que estamos creando una nueva referencia al objeto .

 static PyObject * di_di(PyObject *self, PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args, "l:di", &obj)) return NULL; Py_INCREF(obj); return obj; } 

Si el objeto original ya no existe, el resultado no está definido. Puede fallar, pero también puede devolver una referencia a un nuevo objeto que está tomando la ubicación del antiguo en la memoria.

La biblioteca eGenix mxTools proporciona dicha función, aunque está marcada como “solo para expertos”: mx.Tools.makeref(id)

Esto lo hara:

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

Pero sugiero implementar una forma más decente.