Referencias débiles en python


He estado tratando de entender cómo funciona python weak reference list/dictionary y también he estado leyendo la documentación para ello, sin embargo, parece que no puedo averiguar cómo funcionan y para qué se pueden usar. Alguien podría darme un ejemplo básico de lo que hacen/explicación de cómo funcionan? Se lo agradecería mucho.

(EDITAR) Usando el código de Thomas, cuando sustituyo obj por [1,2,3] arroja:

Traceback (most recent call last):
File "C:/Users/nonya/Desktop/test.py", line 9, in <module>
r = weakref.ref(obj)
TypeError: cannot create weak reference to 'list' object
Author: The6thSense, 2012-03-28

3 answers

Teoría

El recuento de referencias generalmente funciona como tal: cada vez que crea una referencia a un objeto, se incrementa en uno, y cada vez que elimina una referencia, se reduce en uno.

Las referencias débiles le permiten crear referencias a un objeto que no aumentarán el número de referencias.

El recuento de referencia es utilizado por el Recolector de basura de python cuando se ejecuta: cualquier objeto cuyo recuento de referencia sea 0 será recolectado de basura.

Usarías débil referencias para objetos caros, o para evitar referencias circulares (aunque el recolector de basura generalmente lo hace por su cuenta).

Uso

Aquí hay un ejemplo de trabajo que demuestra su uso:

import weakref
import gc

class MyObject(object):
    def my_method(self):
        print 'my_method was called!'

obj = MyObject()
r = weakref.ref(obj)

gc.collect()
assert r() is obj #r() allows you to access the object referenced: it's there.

obj = 1 #Let's change what obj references to
gc.collect()
assert r() is None #There is no object left: it was gc'ed.
 48
Author: Thomas Orozco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-28 13:21:09

Solo quiero señalar que weakref.ref no funciona para la lista incorporada porque no hay __weakref__ en el __slots__ de la lista. Por ejemplo, el siguiente código define un contenedor de lista que admite weakref.

import weakref

class weaklist(list):
    __slots__ = '__weakref__',

l = weaklist()
r = weakref.ref(l)
 16
Author: jichi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-26 20:12:37

El punto es que permiten que se retengan referencias a objetos sin impedir que sean recolectados como basura.

Las dos razones principales por las que querría esto son donde hace su propia administración periódica de recursos, por ejemplo, cerrando archivos, pero debido a que el tiempo entre tales pasadas puede ser largo, el recolector de basura puede hacerlo por usted; o donde crea un objeto, y puede ser relativamente costoso rastrear dónde está en el programa, pero aún desea tratar con instancias que realmente existen.

El segundo caso es probablemente el más común - es apropiado cuando está sosteniendo, por ejemplo, una lista de objetos a notificar, y no desea que el sistema de notificación impida la recolección de basura.

 10
Author: Marcin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-28 13:05:36