Python recipe(15):获取类的所有成员

代码:

div css xhtml xml Example Source Code 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的后面

posted on 2010-05-26 15:42  tomsheep  阅读(5175)  评论(0编辑  收藏  举报

导航