2017-05-17 45 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']