Circular reference problem -- advice?
Sean Blakey
sblakey at freei.net
Mon Jul 10 15:35:59 EDT 2000
On Mon, Jul 10, 2000 at 12:06:46PM -0700, Erik Max Francis wrote:
> I'm fairly new to Python, although it's simple enough that I've already
> been able to write some fairly involved programs in it (I already know
> C, C++, Perl, etc.). This question isn't so much about what's going
> wrong, but rather what's the best, most natural way to get around it.
>
> I've come across a problem due to circular references, and I'm not sure
> what's the best way to tackle it. In essence, the problem is that I
> need a particular class to keep an associative array of its methods for
> a lookup table (it's essentially a dispatcher). But with references to
> its own bound methods, Python's garbage collector concludes it has
> circular references and thus its destructor never gets called.
>
> Here is a simplified standalone program that demonstrates what I'm
> talking about:
>
> class C:
> def __init__(self):
> print "in constructor"
> self.map = { 'f': self.f, 'g': self.g }
>
> def __del__(self):
> print "in destructor"
>
> def f(self):
> print "in C.f"
>
> def g(self):
> print "in C.g"
>
> def dispatch(self, name):
> self.map[name]()
>
>
> c = C()
> c.dispatch('f')
>
> When run, this program prints
>
> max at charmaine:~/tmp% ./circ.py
> in constructor
> in C.f
>
> and that's it; because of the circular reference, the destructor never
> gets called.
>
> For the application I need, it's imperative that the destructor get
> called. What is the best way to solve this? I can think of a few:
>
> - Move the map to a local variable in the dispatching function
> - Make map a lookup table of _unbound_ methods
> - Build a string of the function call and then exec it
>
> What would be the most effective way of getting around this? I'm
> thinking that using unbound methods would probably be the best way.
>
> --
> Erik Max Francis / max at alcyone.com / http://www.alcyone.com/max/
> __ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
> / \ We'll have to make our own luck from now on.
> \__/ Louis Wu
> Computer science / http://www.alcyone.com/max/reference/compsci/
> A computer science reference.
> --
> http://www.python.org/mailman/listinfo/python-list
Is dispatch the only thing you need self.map for? If so, I think the easiest
way around this circular reference may be to reimplement dispatch do that
self.map is unneeded. For example:
def dispatch(self, name):
getattr(self, name)()
Also, your self.map looks like it duplicates the information in the builtin
self.__dict__. Parhaps you could use that instead?
def dispatch(self, name):
self.__dict__[name]()
Either of these solutions will allow you to remove the self.map completely.
-Sean
--
Sean Blakey, sblakey at freei.com
Software Developer, FreeInternet.com
(253)796-6500x1025
"From there to here, from here to there, funny things are everywhere."
-- Dr. Seuss
More information about the Python-list
mailing list