Duncan Booth wrote:
It could happen quite easily if the hash value of the object has changed
since it was put in the dictionary. what does the definition of your
core.gui.FragmentInfo object look like?
Dunno if it'll help much, but:
class FragmentInfo(object):
def __init__(self, renderer, render_area):
self.renderer = renderer
self.render_area = render_area
def __hash__(self):
return hash((FragmentInfo, self.renderer, self.render_area))
def __eq__(self, other):
return (isinstance(other, self.__class__) and
other.renderer == self.renderer and
other.render_area == self.render_area)
Is the hash definitely immutable?
No. It's a hash of a tuple of its key attributes, themselves similar
objects.
The program can be thought of as a map viewer. In the gui part, image
fragments are cached for speed, and fragments are only half rendered if
there's a lot of complex features to draw. The "pool" consists of semi
rendered fragments. The reason I did it this way is the cache. The cache
is a dict with a use tracker so when the hash changes, the older
fragments eventually drop from the cache. Hmm... I'm starting to realise
now why my implementation of this isn't so hot. I'm going to hazard a
guess here, and then you can correct me ok?
I create a dict and populate it with a key-value pair, and then the
key's hash changes. When the key is returned by k = d.keys(), then k not
in d, even though k in d.keys().
Simple example:
class moo(object):
def __init__(self, a):
self.a = a
def __hash__(self):
return hash(self.a)
d = {moo(1): 1}
k = d.keys()[0]
k.a = 2
k = d.keys()[0]
print k in d, k in d.keys()
> d.pop(k)
output:
False True
Traceback (most recent call last):
File "/bioinfo/yohell/eclipse/Test/src/test.py", line 14, in <module>
d.pop(k)
KeyError: <__main__.moo object at 0x7f1c64120590>
I'd say that's pretty similar to what I observed.
I guess the logical outcome is that the cache dict will fill up with old
junk that I can't access and can't selectively flush since the hashes
have changed, unless I actually somehow save copies of the keys, which
can get pretty complex and probably won't do wonders for execution
speed. Yeah this was probably a bad soulution.
I should probably do this with lists instead because I can't really
think of a way of salvaging this. Am i right?
Thanks for your help!
/Joel
--
http://mail.python.org/mailman/listinfo/python-list