2012-02-21 64 views
5

我如何獲得python類的所有屬性名稱,包括那些從超類繼承的屬性?如何訪問Python超類的屬性通過__class __.__ dict__?

class A(object): 
    def getX(self): 
    return "X" 
    x = property(getX) 

a = A() 
a.x 
'X' 

class B(A): 
    y = 10 

b = B() 
b.x 
'X' 

a.__class__.__dict__.items() 
[('__module__', '__main__'), ('getX', <function getX at 0xf05500>), ('__dict__', <attribute '__dict__' of 'A' objects>), ('x', <property object at 0x114bba8>), ('__weakref__', <attribute '__weakref__' of 'A' objects>), ('__doc__', None)] 
b.__class__.__dict__.items() 
[('y', 10), ('__module__', '__main__'), ('__doc__', None)] 

如何訪問通孔b的屬性? 需要:「給我所有的名單財產名稱來自b包括那些從a繼承而來的名字!」

>>> [q for q in a.__class__.__dict__.items() if type(q[1]) == property] 
[('x', <property object at 0x114bba8>)] 
>>> [q for q in b.__class__.__dict__.items() if type(q[1]) == property] 
[] 

我想從第一個(a),第二個(b)工作時獲得結果,但當前只能得到一個空列表。這也應該適用於其它C從B.

繼承
+1

注意'y'不是屬性,它只是一個整數。你是否想要所有不是函數的類變量? – 2012-02-21 12:47:37

+0

如果您關心Python風格([PEP 8](http://www.python.org/dev/peps/pep-0008/)),或者如果不使用'getX',則使用'get_x' t需要能夠執行函數調用版本(如果你通過'super()'---'super(...)來設置一個屬性,那麼x ='Y''將失敗),只需使用'property'作爲裝飾器,作爲'@ property','def x(self):return'X''。 – 2012-02-21 13:31:37

+0

感謝您的評論。我試圖創建一個簡單的例子,而不是我複雜的代碼,是的,因此我沒有考慮PEP8。我不在乎'y'因爲我只需要屬性。 – user1156548 2012-02-21 13:39:15

回答

3

您可以使用dir()

for attr_name in dir(B): 
    attr = getattr(B, attr_name) 
    if isinstance(attr, property): 
     print attr 
+0

好吧,我想這個對於我來說,最後用'print attr_name,attr .__ get __(b)'來工作。謝謝。 – user1156548 2012-02-21 13:20:30

+0

感謝#[email protected]提供的幫助,提供了一個備選答案: '對於b .__類__.__ mro__:如果issubclass(c,A): for c in [ q(for q in c .__ dict __。items()if type(q [1])== property]: print p [0],'=',p [1] .__ get __(b)' – user1156548 2012-02-21 13:34:34

+0

@ user1156548:I不要認爲有必要自己走路。當然你*可以*,但爲什麼*應該*你? – 2012-02-21 13:42:13

1

您可以使用「目錄」,也可以按照全部包含在返回的元組的類「MRO」(方法解析順序,通過對類__mro__屬性中給出) - 這後一種方法是揭示屬性的唯一方法,其中後來被重寫的子類:

>>> class A(object): 
... b = 0 
... 
>>> class B(A): 
... b = 1 
... 
>>> for cls in B.__mro__: 
...  for item in cls.__dict__.items(): 
...   if item[0][:2] != "__": 
...   print cls.__name__, item 
... 
B ('b', 1) 
A ('b', 0) 
>>>