tutorial lenguaje español descargar python

lenguaje - ¿Debería preocuparme por las referencias circulares en Python?



python tutorial (6)

Supongamos que tengo un código que mantiene una estructura padre / hijos. En dicha estructura, obtengo referencias circulares, donde un niño señala a un padre y un padre apunta a un niño. ¿Debería preocuparme por ellos? Estoy usando Python 2.5.

Me preocupa que no se recojan basura y la aplicación eventualmente consumirá toda la memoria.


Experimentalmente: estás bien:

import itertools for i in itertools.count(): a = {} b = {"a":a} a["b"] = b

Se mantiene consistentemente al usar 3.6 MB de RAM.


Las referencias circulares son algo normal que hacer, por lo que no veo motivo para preocuparme por ellas. Muchos algoritmos de árbol requieren que cada nodo tenga enlaces a sus elementos secundarios y sus elementos principales. También se les exige implementar algo así como una lista doblemente vinculada.


No creo que debas preocuparte. Pruebe el siguiente programa y verá que no consumirá toda la memoria:

while True: a=range(100) b=range(100) a.append(b) b.append(a) a.append(a) b.append(b)


Parece que hay un problema con las referencias a los métodos en las listas de una variable. Aquí hay dos ejemplos. El primero no llama a __del__ . El segundo con weakref está bien para __del__ . Sin embargo, en este caso posterior, el problema es que no se puede hacer una referencia débil a los métodos: http://docs.python.org/2/library/weakref.html

import sys, weakref class One(): def __init__(self): self.counters = [ self.count ] def __del__(self): print("__del__ called") def count(self): print(sys.getrefcount(self)) sys.getrefcount(One) one = One() sys.getrefcount(One) del one sys.getrefcount(One) class Two(): def __init__(self): self.counters = [ weakref.ref(self.count) ] def __del__(self): print("__del__ called") def count(self): print(sys.getrefcount(self)) sys.getrefcount(Two) two = Two() sys.getrefcount(Two) del two sys.getrefcount(Two)


Python detectará el ciclo y liberará la memoria cuando no haya referencias externas.


La "preocupación" está fuera de lugar, pero si su programa resulta ser lento, consume más memoria de la esperada o tiene pausas inexplicables, es probable que la causa esté en esos bucles de referencia de basura: deben ser basura recolectada por un procedimiento diferente a los gráficos de referencia "normales" (acíclicos), y esa recopilación es ocasional y puede ser lenta si tiene muchos objetos atados en dichos bucles (la colección de basura cíclica también se inhibe si un objeto en el bucle tiene un __del__ método especial).

Por lo tanto, los bucles de referencia no afectarán la corrección de su programa, pero pueden afectar su rendimiento y / o huella.

Si desea eliminar bucles de referencia no deseados, puede utilizar el módulo weakref en la biblioteca estándar de Python.

Si desea ejercer un control más directo (o realizar una depuración, y ver qué está sucediendo exactamente) con respecto a la recolección cíclica de basura, use el módulo gc en la biblioteca estándar de Python.