Elencare tutte le classi di base in una gerarchia di una determinata classe?


Risposte:


196

inspect.getmro(cls)funziona sia per le classi nuove che per quelle precedenti e restituisce lo stesso di NewClass.mro(): un elenco della classe e tutte le sue classi antenate, nell'ordine utilizzato per la risoluzione del metodo.

>>> class A(object):
>>>     pass
>>>
>>> class B(A):
>>>     pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)

2
Non funziona per le classi pyobjc :( File "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", riga 70, in coerce print inspect.getmro (percorso) File "/System/Library/Frameworks/Python.framework/ Versioni / 2.7 / lib / python2.7 / inspect.py ", riga 348, in getmro searchbases (cls, risultato) File" /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect .py ", riga 339, in _searchbases per base in cls .__ bases_ : AttributeError: l'oggetto ' NSTaggedDate' non ha attributo '__bases '
rbp

17
@rbp Sospetto che tu abbia riscontrato lo stesso problema che ho riscontrato: stavi cercando di fare inspect.getmro(obj)invece di inspect.getmro(type(obj)).
ammettere il

44

Vedi la __bases__proprietà disponibile su un pitone class, che contiene una tupla delle classi di basi:

>>> def classlookup(cls):
...     c = list(cls.__bases__)
...     for base in c:
...         c.extend(classlookup(base))
...     return c
...
>>> class A: pass
...
>>> class B(A): pass
...
>>> class C(object, B): pass
...
>>> classlookup(C)
[<type 'object'>, <class __main__.B at 0x00AB7300>, <class __main__.A at 0x00A6D630>]

5
Ciò può introdurre duplicati. Ed è per questo che la documentazione per getmrodice esplicitamente "Nessuna classe appare più di una volta in questa tupla"?
Sridhar Ratnakumar,

10
Attenzione, __bases__sale solo di un livello . (Come implica la tua utilità ricorsiva, ma uno sguardo superficiale all'esempio potrebbe non riprenderlo.)
Bob Stein

32

inspect.getclasstree()creerà un elenco nidificato di classi e loro basi. Uso:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.

1
Ooh bello. E per risultati ancora più belli, usa pprint! python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
penguin359,

20

puoi usare la __bases__tupla dell'oggetto class:

class A(object, B, C):
    def __init__(self):
       pass
print A.__bases__

La tupla è tornata da __bases__ ha tutte le sue classi base.

Spero che sia d'aiuto!


Se la tua classe eredita da una classe che eredita da una classe, solo la prima parte della catena sarà nella sua__bases__
Boris

Semplice e pulito senza importare un intero modulo per una singola funzione.
Temperosa

8

In Python 3.7 non è necessario importare inspect, type.mro ti darà il risultato.

>>> class A:
...   pass
... 
>>> class B(A):
...   pass
... 
>>> type.mro(B)
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>>

attenzione che in Python 3.x ogni classe eredita dalla classe di oggetti base.


8

Secondo il documento Python , possiamo anche semplicemente usare l' class.__mro__attributo o il class.mro()metodo:

>>> class A:
...     pass
... 
>>> class B(A):
...     pass
... 
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> A.__mro__
(<class '__main__.A'>, <class 'object'>)
>>> object.__mro__
(<class 'object'>,)
>>>
>>> B.mro()
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>> A.mro()
[<class '__main__.A'>, <class 'object'>]
>>> object.mro()
[<class 'object'>]
>>> A in B.mro()
True

2

Sebbene la risposta di Jochen sia molto utile e corretta, poiché puoi ottenere la gerarchia di classi usando il metodo .getmro () del modulo inspect, è anche importante evidenziare che la gerarchia dell'ereditarietà di Python è la seguente:

ex:

class MyClass(YourClass):

Una classe ereditaria

  • Classe per bambini
  • Classe derivata
  • sottoclasse

ex:

class YourClass(Object):

Una classe ereditata

  • Classe genitore
  • Classe base
  • superclasse

Una classe può ereditare da un'altra - Le classi 'attribuite sono ereditate - in particolare, i suoi metodi sono ereditati - questo significa che le istanze di una classe ereditaria (figlio) possono accedere all'attributo della classe ereditata (genitore)

istanza -> classe -> quindi classi ereditate

utilizzando

import inspect
inspect.getmro(MyClass)

ti mostrerà la gerarchia, all'interno di Python.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.