2012-02-21 13 views
5

Come posso ottenere tutti i nomi di proprietà di una classe python comprese quelle proprietà ereditate dalle super classi?Come accedere alle proprietà delle super classi Python, ad es. via __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)] 

Come accedere alle proprietà di una via b? Bisogno: "Dammi un elenco di tutti i proprietà nomi da b compresi quelli ereditati da un!"

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

voglio ottenere risultati del primo (a), quando si lavora con la seconda (b), ma corrente solo può ottenere una lista vuota. Questo dovrebbe funzionare anche per un altro C ereditato da B.

+1

si noti che 'y' non è una proprietà , è solo un numero intero. Vuoi tutte le variabili di classe che non sono forse funzioni? –

+0

Invece di avere 'getX', avere' get_x' se ti interessa lo stile Python ([PEP 8] (http://www.python.org/dev/peps/pep-0008/)), o se non lo fai Devo essere in grado di fare la funzione chiamata versione (lo farai se mai andrai ad impostare una proprietà tramite 'super()' --- 'super (...). x = 'Y'' fallirà), usa 'property' come decoratore, come' @ property', 'def x (self): return 'X''. –

+0

Grazie per questi commenti. Ho provato a creare un semplice esempio al posto del mio codice complesso e sì, non ho quindi pensato a PEP8. Non mi interessa per questo, perché ho solo bisogno delle proprietà. – user1156548

risposta

3

È possibile utilizzare dir():

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

Ok, immagino che lavora per me con un 'print attr_name, attr .__ get __ (b)' alla fine. Grazie. – user1156548

+0

Grazie per aiutare il #[email protected] per un suggerimento che porta a una risposta alternativa: 'per c in b .__ class __.__ mro__: se issubclass (c, A): per p in [ q per q in c .__ dict __. items() se type (q [1]) == proprietà]: print p [0], '=', p [1] .__ get __ (b) ' – user1156548

+0

@ user1156548: I non pensare che sia necessario guidare l'MRO da solo. Certo che * puoi *, ma perché * dovresti * tu? –

1

È possibile utilizzare "dir", oppure è possibile seguire tutte le classi che sono contenuti nella tupla restituita da (ordine di risoluzione metodo, dato dall'attributo __mro__ sulla classe) "MRO" - questo metodo seguito è l'unico modo di scoprire dove attributi che successivamente sovrascritto dalle sottoclassi:

>>> 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) 
>>> 
Problemi correlati