tutorial lenguaje espaƱol descargar python

lenguaje - python tutorial



Obtener objeto por id()? (7)

Digamos que tengo una identificación de un objeto Python, que recuperé al hacer id(thing) . ¿Cómo puedo encontrar thing nuevamente con el número de identificación que me dieron?


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.


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


Probablemente quiera considerar implementarlo de otra manera. ¿Conoces el módulo weakref?

(Editado) El módulo Python weakref le permite guardar referencias, referencias de diccionario y proxies en objetos sin tener que contar esas referencias en el contador de referencia. Son como enlaces simbólicos.


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


Respuesta corta, no puedes.

Respuesta larga, puede mantener un dict para asignar identificadores a los objetos, o buscar el ID mediante una búsqueda exhaustiva de gc.get_objects() , pero esto creará uno de dos problemas: o bien la referencia del dict mantendrá el objeto vivo y evitará el GC , o (si es un dict de WeakValue o usa gc.get_objects() ) la ID puede desasignarse y reutilizarse para un objeto completamente diferente.

Básicamente, si estás tratando de hacer esto, probablemente necesites hacer algo diferente.


Si el objeto aún está allí, esto se puede hacer por 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 bloqueos extraños o cosas peores, así que tenga cuidado.


Solo mencionando este módulo para completarlo. Este código de Bill Bumgarner incluye una extensión C para hacer lo que quiera sin pasar por todos los objetos que existen.

El código para la función es bastante sencillo. Cada objeto Python se representa en C mediante un puntero a una estructura PyObject . Como id(x) es solo la dirección de memoria de esta estructura, podemos recuperar el objeto de Python simplemente tratando x como un puntero a un PyObject , y luego llamando 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 bloquearse, pero también podría devolver una referencia a un nuevo objeto que ha tomado la ubicación del anterior en la memoria.