Circular references (was: Defining VCL-like framework for Py
Gordon McMillan
gmcm at hypernet.com
Thu May 20 16:00:03 EDT 1999
Ce'Nedra, er, Hans wrote:
> On 20 May 99, Ce'Nedra took her magical amulet and heard Graham
> Matthews say:
> >The problem is that as I understand the Python implementation you can very
> >easily make circular refs the without even knowing you are doing it via
> >globals. Or has this been changed?
>
> I don't know very much about this subject... I know it can be a
> problem with deleting objects... they sit in memory because there's
> still a reference to them, while you thought you deleted it. I can't
> really give an example though. I didn't hear about circular
> references via globals without even knowing it.
>
> I'm sure there are people who have more to say on this... *hint*
Oh all right.
I'm not sure where "globals" crept into this. If you have a global
reference, the referenced object ain't going away. You can have
*hidden* global references, but that's another problem, and it's not
particular to Python's ref counting scheme.
The problem is _usually_ a parent / child thing, where each has a
reference to the other. You cut them loose, but they don't go away
because each has another object (the other) referencing them.
You don't need to break _both_ references, just one of them. Simple
way out: give one of the objects a free() method which just says
"self.parent = None". Now you need to remember to call free() when
you're done with it.
Another way is to put one of them (the parent, normally) in some
kind of collection, (say, a dict keyed by a name, like id(parent)).
Tell the child the parent's name and the collection. When you cut the
parent loose from the dict, it goes away (the child does not directly
reference it). Then the child goes away (nobody is referencing it).
You can probably think of other ways of dealing with it. The
important part is recognizing them. Some of them can be subtle.
class LivesForever:
def __init__(self):
self.me = self
Despite these drawbacks, I generally prefer ref counting to garbage
collection. GC is generally nondeterminant - you know it _will_
happen, but you have no idea _when_. So if your objects have some
kind of outside resource open, you need to have a special free()
method anyway instead of relying on freeing it in the destructor.
I realize many people feel strongly the other way, and I'm not going
to fight about it. Neither solution is perfect. I'm just stating my
preference.
- Gordon
More information about the Python-list
mailing list