2014-02-21 83 views
19

假設o是一個Python對象,我希望所有字段的o,沒有任何方法或__stuff__。如何才能做到這一點?如何列出類的所有字段(並且沒有方法)?

我已經試過了諸如:

[f for f in dir(o) if not callable(f)] 

[f for f in dir(o) if not inspect.ismethod(f)] 

但這些回報一樣dir(o),大概是因爲dir給出一個字符串列表。此外,像__class__這樣的東西將會在這裏返回,即使我得到這個工作。

+0

我一直在使用['inspect'](http://docs.python.org/2/library/inspect.html),但無法100%正確,但該模塊可能有幫助嗎? – 2rs2ts

+0

我已經看過檢查也... –

+0

可能重複的[從對象的字段的Python字典](http://stackoverflow.com/questions/61517/python-dictionary-from-an-objects-fields) –

回答

28

您可以通過__dict__屬性得到它,或built-in vars功能,這僅僅是一個快捷方式:

>>> class A(object): 
...  foobar = 42 
...  def __init__(self): 
...   self.foo = 'baz' 
...   self.bar = 3 
...  def method(self, arg): 
...   return True 
... 
>>> a = A() 
>>> a.__dict__ 
{'foo': 'baz', 'bar': 3} 
>>> vars(a) 
{'foo': 'baz', 'bar': 3} 

只有對象的屬性。方法和類屬性不存在。

+0

這是每個實例。 – 2rs2ts

+3

這可能是您要得到的最佳逼近,但應該注意的是,這將可調用實例屬性(有時使用並且實際上類似於方法)視爲非方法,並且將類屬性視爲沒有對應的實例屬性一個領域(儘管它在大多數情況下表現得像一個領域)。它也忽略了屬性,並且在'__slots__'上失敗,這可能也可能不重要。 – delnan

2

這應該可調用工作:

[f for f in dir(o) if not callable(getattr(o,f))] 

能否通過擺脫休息:

[f for f in dir(o) if not callable(getattr(o,f)) and not f.startswith('__')] 
+0

幾乎。我用'a'和'b'作爲類成員的虛擬類獲得了'['__dict__','__doc__','__module__','__weakref__','a','b']''。 – 2rs2ts

+0

關閉,但仍包含'__dict__','__doc__'等。 –

3

你可以使用內置的方法vars()

6

最基本的答案是:「你不能這樣做可靠」。見this question

您可以通過[attr for attr in dir(obj) if attr[:2] + attr[-2:] != '____' and not callable(getattr(obj,attr)]獲得近似值。

但是,你不應該依賴於這一點,because

因爲dir()主要提供作爲進行交互提示符中使用的便利性,它會嘗試比它試圖提供的名字一套有趣的多提供嚴格或一致定義的一組名稱,其詳細行爲可能在不同版本中發生變化。

換句話說,沒有規範的方式來獲取「所有對象的屬性」(或「所有對象的方法」)列表。

如果您正在做某種動態編程,需要您對對象的未知字段進行迭代,唯一可靠的方法就是實現自己的跟蹤這些字段的方式。例如,您可以使用屬性命名約定或特殊的「字段」對象,或者最簡單的說,就是一個字典。

+0

我不確定,但是如果您可以創建由雙下劃線包圍的自己的成員,則會中斷。 – 2rs2ts

+3

@ 2rs2ts:是的,那是真的。這是沒有辦法的。沒有辦法通過編程來判斷雙下劃線名稱是否是「魔術」的;你必須閱讀文檔。 – BrenBarn

+3

這些是命名約定,您不應通過用雙下劃線包圍它們來創建自己的成員。 –

3

您可以遍歷實例的__dict__屬性並查找非方法的東西。
例如:

CALLABLES = (types.FunctionType, types.MethodType) 
for key, value in A().__dict__.items(): 
    if not isinstance(value, CALLABLES): 
     print key 

輸出:

foo 
bar 

你可以做到這一點與列表理解單個語句:

print [key for key, value in A.__dict__.items() 
      if not isinstance(value, CALLABLES)] 

這將打印['foo', 'bar']

+0

沒有必要過濾掉方法,因爲它們在類__dict__中,而不是實例__dict__。 – Blckknght

+0

@Blckknght:我把測試放在因爲一個類也是一個對象。但是,我意識到您的評論後,需要檢查超過一種類型的可調用,並修改了我的答案。謝謝。如果可以假設對象是一個新型的類實例,那麼你所說的是真的,for循環可以被簡化。 – martineau

相關問題