Can somebody explain to me why this works (in Python 2.5) :
class Foo(object):
pass
class Bar(Foo):
pass
print(Foo.__subclasses__())
but this doesn’t :
class Foo():
pass
class Bar(Foo):
pass
print(Foo.__subclasses__())
The latter returns “AttributeError: class Foo has no attribute ‘__subclasses__‘” but i’m not sure why. I know this is related to old-style vs. new-style classes but i’m not clear on why that would make this functionality unavailable.
Clarification: I’m looking to understand WHY __subclasses__() isn’t available in old-style, i get that the method doesn’t exist for old-style classes but I don’t get what it is about new-style that makes these new functions possible.
The class above is a “new-style” class because it inherits from the object class. New-style classes provide a lot of extra framework that “old-style” classes do not have. One particular attribute of a new-style class is to be able to determine the subclasses of the class with the __subclasses__ method.
There is some good discussion about new-style classes and the __subclasses__ method which use to be completely undocumented. ( Here is an unofficial explanation from Tim Peters, though. )
“Each new-style class keeps a list of weak references to its immediate subclasses. This method returns a list of all those references still alive.”
So to answer your question, the __subclasses__ functionality is not available because in your second example:
The old-style class Foo does not inherit from object (so it’s not a new-style class) and there for does not inherit the __subclasses__ method.
Note, if you don’t understand why an old-style class does not have the __subclasses__ method you could always fire up a python interpreter and do some inspection with dir