2017-05-17 47 views
1

可以说我有包含在构造函数创建的属性的混合Python类,并使用property装饰创建计算性能:获取包含Python对象计算属性的字典?

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并以某种方式筛选出不中断的部分?

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

+0

'foo'是属性,而不是属性。 –

+0

不确定是否足够,但所有“垃圾”以__开头,为什么不过滤?如果不是i.startswith(“__”)]' –

+2

'我想我将不得不重写'__dict__'“ - 不这样做。它打破了太多的期望和太多的代码。他们用'namedtuple'试了一下,这是一个糟糕的主意,他们不得不改变它。 – user2357112

回答

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']