Come posso ottenere le classi genitore di una classe Python?
Come posso ottenere le classi genitore di una classe Python?
Risposte:
Usa il seguente attributo:
cls.__bases__
Dai documenti :
La tupla di classi base di un oggetto classe.
Esempio:
>>> str.__bases__
(<type 'basestring'>,)
Un altro esempio:
>>> class A(object):
... pass
...
>>> class B(object):
... pass
...
>>> class C(A, B):
... pass
...
>>> C.__bases__
(<class '__main__.A'>, <class '__main__.B'>)
Se vuoi tutti gli antenati anziché solo quelli immediati, usa inspect.getmro :
import inspect
print inspect.getmro(cls)
Utilmente, questo ti dà tutte le classi di antenati nell '"ordine di risoluzione del metodo" - cioè l'ordine in cui gli antenati verranno controllati quando si risolve un metodo (o, in realtà, qualsiasi altro attributo - metodi e altri attributi vivono nello stesso spazio dei nomi in Python, dopo tutto ;-).
cls.__mro__
(almeno in Python 3.5)
Le classi di nuovo stile hanno un metodo mro che puoi chiamare che restituisce un elenco di classi principali in ordine di risoluzione del metodo.
object
non sembra rispondere mro
.
x
, possiamo ottenere l'ordine di risoluzione del metodo con la chiamata type(x).mro()
che possiamo considerare se x
ha ClassX
come classe base con: ClassX in type(x).mro()
Il modo PIÙ VELOCE , per vedere tutti i genitori, e IN ORDINE , basta usare il built-in__mro__
vale a dire repr(YOUR_CLASS.__mro__)
>>>
>>>
>>> import getpass
>>> getpass.GetPassWarning.__mro__
uscite, IN ORDINE
(<class 'getpass.GetPassWarning'>, <type 'exceptions.UserWarning'>,
<type 'exceptions.Warning'>, <type 'exceptions.Exception'>,
<type 'exceptions.BaseException'>, <type 'object'>)
>>>
Ecco qua. La risposta "migliore" in questo momento, ha 182 voti (mentre lo sto scrivendo) ma è molto più semplice di un ciclo contorto, che esamina le basi una classe alla volta, per non parlare quando una classe estende DUE o più genitori classi. L'importazione e l'utilizzo di inspect
cloud semplicemente non è necessario. Onestamente è un peccato che la gente non sappia usare solo i built-in
Spero che aiuti!
inspect.getmro
chiama semplicemente __mro__
l'oggetto, come puoi vedere in github.com/python/cpython/blob/… . L'utilizzo getmro
produce un codice più pulito e più leggibile. Anche se saltare una chiamata di funzione è davvero più veloce.
Usa le basi se vuoi solo ottenere i genitori, usa __mro__
(come sottolineato da @ naught101) per ottenere l'ordine di risoluzione del metodo (in modo da sapere in quale ordine sono stati eseguiti gli init).
Basi (e prima ottenere la classe per un oggetto esistente):
>>> some_object = "some_text"
>>> some_object.__class__.__bases__
(object,)
Per mro nelle recenti versioni di Python:
>>> some_object = "some_text"
>>> some_object.__class__.__mro__
(str, object)
Ovviamente, quando hai già una definizione di classe, puoi semplicemente chiamarla __mro__
direttamente:
>>> class A(): pass
>>> A.__mro__
(__main__.A, object)
type(C()).__bases__
come indicato più avanti