From the reference documentation for __subclasses__
:
Each class keeps a list of weak references to its immediate subclasses. This method returns a list of all those references still alive. The list is in definition order.
The give-away is “weak”. It is obviously meant to not be up-to-date, so I expect your wish to make it so will not be granted.
When you look at the list when it is up-to-date, there may be surprises. I altered your first example a little:
>>> class Foo():
... pass
...
>>> class Bar(Foo):
... a = "Old foo"
...
>>> class Baz(Bar):
... pass
...
>>> class Bar():
... pass
...
>>> bazzie = Baz()
>>> bazzie.a
'Old foo'
>>> barrie = Bar()
>>> barrie.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Bar' object has no attribute 'a'
The “old” Bar is not reachable through the name Bar any more, but it does still exist. It is referenced from Baz, so not GC-ed. Two Bar entries in __subclasses__
, and rightfully so.
I would try to keep out of keeping track of subclasses, it is hardly ever worth while.
As said before, don’t bother.
No, when you use the entries in __subclasses__
, be aware they may be dead and catch the TypeError.