El algoritmo de gestión de memoria de Python utiliza un mecanismo de recuento de referencias para la recolección de elementos no utilizados , que realiza un seguimiento de todos los objetos accesibles. Todos los objetos de Python incluyen un campo de recuento de referencias, que cuenta cuántos objetos hacen referencia a él. Si otro objeto hace referencia a un objeto, su contador se establece en un número distinto de cero y el objeto no se puede recolectar basura. Si el contador llega a cero, el recolector de basura liberará ese objeto.
A continuación se muestra un breve ejemplo de cómo podemos encontrar el recuento de referencias de cualquier objeto en python.
Python3
import ctypes # list object which is referenced by # my_list my_list = [1, 2, 3] # finding the id of list object my_list_address = id(my_list) # finds reference count of my_list ref_count = ctypes.c_long.from_address(my_list_address).value print(f"Reference count for my_list is: {ref_count}")
Producción:
Reference count for my_list is: 1
Entonces, ahora que tenemos claro los conceptos básicos de las referencias y las recolecciones de basura, pasemos a lo que son las referencias débiles y por qué las necesitamos.
¿Qué es la referencia débil?
A diferencia de las referencias que discutimos anteriormente , una referencia débil es una referencia que no protege al objeto de la recolección de basura. ¿Por qué queremos tal cosa en primer lugar?
Hay dos aplicaciones principales de las referencias débiles:
- Implemente cachés para objetos grandes (diccionarios débiles).
- Reducción del Dolor a partir de referencias circulares.
Para crear referencias débiles, Python nos ha proporcionado un módulo llamado ref débil . Un punto a tener en cuenta antes de usar la referencia débil es que algunos componentes como tuple o int no lo admiten. el soporte de list y dict es cualquiera, pero podemos agregar soporte a través de subclases. Analicemos las aplicaciones en detalle.
Módulo de referencia débil
A veces, un objeto grande se almacena en el caché, por lo que no es necesario mantenerlo vivo. Vamos a tener una gran cantidad de objetos de imagen y se están utilizando como claves para mapear imágenes debido a que estos objetos se mantendrán vivos.
Afortunadamente, el módulo de ref débil proporciona algo llamado WeakKeyDictionary y WeakValueDictionary no mantiene vivos los objetos tal como aparecen en los objetos de mapeo.
Las siguientes clases y métodos son proporcionados por el módulo de ref. débil :
- clase debilref.ref(objeto[, devolución de llamada]) – Esto devuelve una referencia débil al objeto.
- débilref.proxy ( objeto [, devolución de llamada ]): esto devuelve un proxy al objeto que usa una referencia débil.
- débilref.getweakrefcount( objeto ) – Devuelve el número de referencias débiles y proxies que se refieren al objeto .
- débilref.getweakrefs ( objeto ) : devuelve una lista de todos los objetos proxy y de referencia débil que se refieren al objeto.
Entendamos el trabajo con algunos ejemplos:
Ejemplo 1:
En el ejemplo a continuación, creamos un objeto de lista normal, un objeto de lista de referencia débil y un objeto de lista de proxy e imprimimos el recuento de referencia débil para todos ellos.
Python3
# importing weakref module import weakref # creating a class class GFG(list): pass # creating object of a class obj = GFG("Geeks") # creating a normal list object normal_list = obj print(f"This is a normal object: {normal_list}") # this returns a weak reference to obj weak_list = weakref.ref(obj) weak_list_obj = weak_list() print(f"This is a object created using weak reference: {weak_list_obj}") # creating a proxy of original object proxy_list = weakref.proxy(obj) print(f"This is a proxy object: {proxy_list}") # printing the count of weak references for objects in [normal_list, weak_list_obj, proxy_list]: print(f"Number of weak references: {weakref.getweakrefcount(objects)}")
Producción:
Este es un objeto normal: [‘G’, ‘e’, ’e’, ’k’, ‘s’]
Este es un objeto creado usando una referencia débil: [‘G’, ‘e’, ’e’, ’ k’, ‘s’]
Este es un objeto proxy: [‘G’, ‘e’, ’e’, ’k’, ‘s’]
Número de referencias débiles: 2
Número de referencias débiles: 2
Número de referencias débiles : 0
Como el objeto normal tiene referencias al objeto de referencia débil, ambos tienen un recuento de referencia débil de 2, pero como proxy_object es un proxy creado a partir de la referencia débil, por lo que no tiene un recuento de referencia.
Ejemplo 2:
En este ejemplo, veremos cómo usar WeakValueDictionary que discutimos anteriormente en el artículo.
Python3
# import weakref module import weakref # creates a class class GFG: def __init__(self,data): self.data = data def __repr__(self): return str(self.data) # creates an object of class GFG # (consider that this object is very # large and has been stored in the cache) value = GFG(5) # creates a Weak Value Dictionary weak_dict = weakref.WeakValueDictionary() # inserting value into the dictionary weak_dict["num"] = value # getting the weak ref count print(f'Weak reference count is: {weakref.getweakrefcount(weak_dict)}') # deleting the weak dictionary del weak_dict # running this will generate error # print(weak_dict)
Producción:
Weak reference count is: 1
En el ejemplo anterior, asumimos que hay un objeto realmente grande que se ha colocado en el caché, por lo que hemos creado un diccionario de referencia débil para almacenar ese par de clave y valor para que se recopile como basura.
Publicación traducida automáticamente
Artículo escrito por nishkarsh146 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA