I have a class that keeps track of its instances in a class variable, something like this:
class Foo:
by_id = {}
def __init__(self, id):
self.id = id
self.by_id[id] = self
What I’d like to be able to do is iterate over the existing instances of the class. I can do this with:
for foo in Foo.by_id.values():
foo.do_something()
but it would look neater like this:
for foo in Foo:
foo.do_something()
is this possible? I tried defining a classmethod __iter__, but that didn’t work.
If you want to iterate over the class, you have to define a metaclass which supports iteration.
x.py:
As you can see in the end, deleting an instance will not have any effect on the object itself, because it stays in the
by_iddict. You can cope with that usingweakrefs when youand then do
. This way the values will only kept as long as there is a “strong” reference keeping it, such as
ain this case. Afterdel a, there are only weak references pointing to the object, so they can be gc’ed.Due to the warning concerning
WeakValueDictionary()s, I suggest to use the following:Looks a bit complicated, but makes sure that you get the objects and not a
weakrefobject.