从Python对象获取包含计算属性的字典?

时间:2017-05-17 22:39:35

标签: python class dictionary

假设我有一个Python类,其中包含在构造函数中创建的混合属性以及使用property装饰器创建的计算属性:

class Example:

    def __init__(self):
        self.foo = 1

    @property
    def bar(self):
        return 2

    def baz(self, x):
        return x * x

我想生成一个包含两种属性的字典,但没有别的。但是,如果我vars(Example()),我只会foo。如果我dir(Example())我同时获得了foobar,但baz和其他垃圾也是如此。

是否可以自动生成这样的字典?我想我必须覆盖__dict__?或许可以通过调用dir并以某种方式过滤掉那些不明显的部分?

我想避免手动枚举所有属性。

1 个答案:

答案 0 :(得分:1)

这里的根本问题是dir返回:

Else, return an alphabetized list of names comprising (some of) the attributes
    of the given object, and of attributes **reachable** from it

但是foo 不是该实例的属性,它是 属性的属性实例,因此它包含在dir输出中,但缺少实例的__dict__。检查Example.__dict__。在类块中定义的Python中的所有属于类。但是在__init__方法中,您明确指定了self.foo = val,它分配给实例

考虑:

In [2]: e = Example()

In [3]: e.__dict__
Out[3]: {'foo': 1}

In [4]: Example.__dict__
Out[4]:
mappingproxy({'__dict__': <attribute '__dict__' of 'Example' objects>,
              '__doc__': None,
              '__init__': <function __main__.Example.__init__>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'Example' objects>,
              'bar': <property at 0x104214408>})

也许最简单的解决方案是利用dir可达属性的认知,并结合以下过滤操作:

In [12]: list(s for s in dir(e) if not callable(getattr(e, s)) and not s.startswith('__'))
Out[12]: ['bar', 'foo']