Haven't done this for a few weeks, mostly due to lack of time, to some extent running out of obscure Python puzzles... But maybe it's useful to cover some simpler gotchas too. This one's rather easier than the previous ones, but it still might be easy to miss what's going on.
Suppose you wanted to design a class which kept track of all the different instances of it which were created. You might imagine a class like this:
class Counted(object):
instances = set()
def __init__(self):
self.instances.add(self)
def __del__(self):
self.instances.discard(self)
Seems simple enough - there's a class variable instances
which is a set()
of all the instances created by __init__()
. When the class is garbage-collected, __del__()
removes the reference from the set, so it should always contain the current references. Right?
So, let's test this class in an interactive session:
>>> print len(Counted.instances)
0
>>> local_instances = [Counted() for i in xrange(10)]
>>> print len(Counted.instances)
10
Looks good - we've created a list of 10 instances, and now Counted.instances
contains 10 items, just as it should. OK, so now we delete local_instances
and the count should go back to zero:
>>> del local_instances
>>> print len(Counted.instances)
10
Hm, still 10... What's going on?
EDIT
Bonus section... After running the above code, try then executing the following and watch the fireworks:
>>> del Counted.instances
(Note: Don't do this in a Python interpreter session you care about!)