I found the following function, but I have no idea why additional __bases__ scan is required:
def getMembersWithBases(classType):
members = set(dir(classType))
# recursive bases scan
for baseClassType in classType.__bases__:
members.update(getMembersWithBases(baseClassType))
return members
The following function is faster and gives same results – so why is the additional __bases__ scan needed at al?
def getMembers(classType):
members = set(dir(classType))
return members
Some test code with both new- and old-style classes:
class Father(object):
def testFather():
pass
class Mother(object):
def testMother():
pass
class Child(Father, Mother):
def testChild():
pass
print type(Child)
print getMembers(Child) == getMembersWithBases(Child)
class Father:
def testFather():
pass
class Mother:
def testMother():
pass
class Child(Father, Mother):
def testChild():
pass
print type(Child)
print getMembers(Child) == getMembersWithBases(Child)
Result:
<type 'type'>
True
<type 'classobj'>
True
Indeed, the
dir()function, for classes, already includes all the classes listed in__bases__:However, it is possible for a class to override that behaviour by specifying a
__dir__method (via a metaclass, a classmethod is not enough):When a
__dir__()method is present,__bases__is not recursed over:Thus, the explicit recursion over
__bases__in thegetMembersWithBases()class method could be an attempt at bypassing any custom__dir__()implementations.Otherwise, the recursion over
__bases__is completely redundant.In my personal opinion, the recursion over
__bases__is redundant even if there are__dir__()methods present in the class hierarchy. In such cases, the__dir__()method override is at fault as that method should recurse over the classes listed in__bases__to correctly mimic the behaviour of thedir()function.To be honest, I suspect that the author of the function that you found was not aware of the recursive nature of
dir(), and added the__bases__recursion needlesly, not as a means to bypass custom__dir__()methods.