2012-03-28 14 views
32

He estado tratando de entender cómo funciona el diccionario/lista de referencia de python y he leído la documentación también, sin embargo, no puedo entender 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? Sería muy apreciado.Referencias débiles en python

(EDIT) Mediante el código de Thomas, cuando sustituyo obj para [1,2,3] se lanza:

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 

Respuesta

41

Teoría

El recuento de referencia por lo general funciona como tal: cada vez que se crea una referencia a un objeto, éste se incrementa en uno, y cada vez que se elimina una referencia, se disminuye en uno.

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

El contador de referencias es utilizado por el recolector de basura de Python cuando se ejecuta: cualquier objeto cuyo recuento de referencia sea 0 será basura.

Utilizaría referencias débiles para objetos costosos, o para evitar referencias circulares (aunque el recolector de basura por lo general lo hace solo).

Uso

Aquí está 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. 
+0

¿Cómo funciona en list/dictionary's, sin embargo, este fue un gran ejemplo en clases/funciones. :) –

+0

¿Podría mirar mi edición? cuando se sustituye una lista o diccionario, arroja ese error. –

+0

Malo, pasé por alto esto, no se puede crear weakref en una "lista" u otro tipo de compuesto: ¿cuál es su propósito exacto para el que lo necesita? –

9

El punto es que permiten que las referencias que deben conservarse a objetos sin evitando que sean recogidos de la basura.

Las dos razones principales por las que usted desearía esto es donde usted hace su propia administración de recursos periódica, p. cierre de archivos, pero debido a que el tiempo entre dichos pasos 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 las instancias que realmente existen.

El segundo caso es probablemente el más común; es apropiado cuando está sosteniendo, p. una lista de objetos para notificar y no desea que el sistema de notificación evite la recolección de basura.

+0

¿Tal vez 3 razones? tercero, la ruptura de las referencias cíclicas. – dashesy

+1

@dashesy tiene razón. El caso de uso más común (sin dudas, el único seguro) para las referencias débiles es romper explícitamente los ciclos de referencia. Aunque el recolector de basura de Python puede y eventualmente romperá dichos ciclos de todos modos, es mucho menos intenso en cuanto al espacio y el tiempo para evitar que se formen dichos ciclos en primer lugar. Todos los otros usos de las referencias débiles son, en el mejor de los casos, frágiles y deberían ser tratados absolutamente con un mínimo de temor y respeto. –

12

Sólo quiero señalar que weakref.ref no funciona para incorporado en la lista porque no hay __weakref__ en el __slots__ de 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) 
Cuestiones relacionadas