获取python对象派生属性

时间:2014-05-26 15:02:34

标签: python

所以我想从对象中获取所有属性,我在网上找到了这个代码:

class A(object):

    @property
    def typeInfo(self):
        return "type_A"

    def properties(self):
        result={}
        for cls in self.__class__.__mro__:
            for varname, value in cls.__dict__.iteritems():
                if isinstance(value, property):
                    result[varname] = value.fget(self)
        return result

但是当我开始定义类A派生的类时:

class B(A):

    @property
    def typeInfo(self):
        return "type_B"

我遇到了以下问题:

a = A()
b = B()

a.typeInfo #returns: type_A
b.typeInfo #returns: type_B

a.properties #returns: {'typeInfo': 'type_A'}
b.properties #returns: {'typeInfo': 'type_A'}

所以我意识到我并没有完全理解我发现的代码是什么,并开始挖掘更多。我发现了其他代码:

def properties2(self):
    result={}
    for cls in self.__class__.__mro__:
        for varname, value in cls.__dict__.iteritems():
            if isinstance(value, property):
                result[varname] = getattr(self, varname)
    return result

会返回:

a.properties2 #returns: {'typeInfo': 'type_A'}
b.properties2 #returns: {'typeInfo': 'type_B'}

好的,现在我承认我真的不明白其中的区别 为什么第一个解决方案是返回父值而不是它自己的值?

以下是方便的完整代码:

class A(object):

    def __init__(self):
        self._name = "default name"

    @property
    def typeInfo(self):
        return "type_A"

    def properties(self):
        result={}
        for cls in self.__class__.__mro__:
            for varname, value in cls.__dict__.iteritems():
                if isinstance(value, property):
                    result[varname] = value.fget(self)
        return result

    def properties2(self):
        result={}
        for cls in self.__class__.__mro__:
            for varname, value in cls.__dict__.iteritems():
                if isinstance(value, property):
                    result[varname] = getattr(self, varname)
        return result

class B(A):

    @property
    def typeInfo(self):
        return "type_B"


a = A()
b = B()

print "a.typeInfo:\t", a.typeInfo
print "b.typeInfo:\t", b.typeInfo
print ""
print "With properties:"
print "a.properties:\t", a.properties()
print "b.properties:\t", b.properties()
print ""
print "With properties2:"
print "a.properties2:\t", a.properties2()
print "b.properties2:\t", b.properties2()

1 个答案:

答案 0 :(得分:0)

首先请注意,您要分配两次相同的字典项目。 varnameB的{​​{1}}相同。因此,当您从A的{​​{1}}阴影属性运行b.properties()属性时。

对于第二个示例,在致电A时,您永远不会尝试访问B。函数结束两次调用A.typeInfo()

您可以修复它,例如,在b.properties2()前加上类名。如果您不存储被覆盖的属性,则可以还原getattr(b, 'typeInfo')列表。