Python recipe(15):获取类的所有成员
代码:
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)的话总会返回<type ‘instance’>, 可见在底层实现中旧式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的后面