代码:
Example Source Code [http://www.cnblogs.com/tomsheep/]
'''
Created on 2010-5-26
@author: lk
'''
def all_members(aClass):
try:
#new type class
mro = list(aClass.__mro__)
except AttributeError:
#old type class
def getmro(aClass,recurse):
# print 'getmro:',aClass.__name__
mro = [aClass]
for base in aClass.__bases__:
mro.extend(recurse(base,recurse))
return mro
def getmro1(aClass):
mro = [aClass]
for base in aClass.__bases__:
mro.extend(getmro1(base))
return mro
mro = getmro(aClass,getmro)
# mro = getmro1(aClass)
mro.reverse()
print aClass.__name__,"mro:",mro
members = {}
for someClass in mro:
members.update(vars(someClass))
return members
class A1:
'''A1 doc'''
a = 1
class A2(A1):
'''A2 doc'''
a = 2
class A3(A2):
'''A3 doc'''
a = 3
class B1(object):
'''B1 doc'''
a = 1
class B2(B1):
'''B2 doc'''
a = 2
class B3(B2):
'''B3 doc'''
a = 3
if __name__ == '__main__':
print all_members(A3)
print all_members(B3)
以上代码改写自Python Cookbook 5-3
概述:
获取一个类对象(非实例)的所有成员
代码说明:
1. python 新旧class: 旧式class不以object为根,如果type一个旧式class的实例,type(oldClassObj)的话总会返回, 可见在底层实现中旧式class的实例全都是以一个内建类型instance实现的。而新式class以object为根,如果type一个新式class实例,会返回该自定义的type,可见新式class才真正允许用户自定义“类型”。
2. 在本例中获取mro(该类的相关类型,即直接与间接父类)时对新旧class进行了区分,因为新式class本身就包括了__mro__这个属性。获得后对mro列表进行反转是因为mro本来的顺序是[孙子,父亲,爷爷,太爷爷……],在本例中我们想要反过来是因为如果父类子类有同名属性,在后面的members.update时,我们希望留到最后是最下层的属性。
3.getmro方法看上去奇怪是因为老版本的python不支持像getmro1这样的递归形式
4.vars函数等同于获取对象的__dict__属性
5.list的extend(x)函数相当于alist[len(alist):len(alist)]=x,要求x必须是iterable对象,将x中的所有元素追加到alist的后面