Listar todas as classes base em uma hierarquia de determinada classe?

Respostas:

196

inspect.getmro(cls)funciona para as classes de estilo novo e antigo e retorna o mesmo que NewClass.mro(): uma lista da classe e todas as suas classes ancestrais, na ordem usada para a resolução do método.

>>> class A(object):
>>>     pass
>>>
>>> class B(A):
>>>     pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
Jochen Ritzel
fonte
2
Não funciona para as classes pyobjc :( Arquivo "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", linha 70, para coagir a impressão inspect.getmro (caminho) Arquivo "/System/Library/Frameworks/Pramthon.framework/ Versões / 2.7 / lib / python2.7 / inspect.py ", linha 348, nas bases de pesquisa getmro (cls, resultado) Arquivo" /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect .py ", linha 339, em _searchbases para base em cls .__ bases_ : AttributeError: ' NSTaggedDate' objeto não tem nenhum atributo '__bases '
rbp
17
@ rbp Eu suspeito que você teve o mesmo problema que eu encontrei: você estava tentando fazer em inspect.getmro(obj)vez de inspect.getmro(type(obj)).
21820 esmit
44

Veja a __bases__propriedade disponível em um python class, que contém uma tupla das classes de bases:

>>> 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>]
Crescent Fresh
fonte
5
Isso pode introduzir duplicatas. E é por isso que a documentação para getmroexplicitamente diz "Nenhuma classe aparece mais de uma vez nesta tupla"?
Sridhar Ratnakumar 9/09/09
10
Cuidado, __bases__apenas sobe um nível . (Como sua utilidade recursiva implica, mas um breve olhar sobre o exemplo pode não pegar em que.)
Bob Stein
32

inspect.getclasstree()criará uma lista aninhada de classes e suas bases. Uso:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.
Ned Batchelder
fonte
1
Ooh legal. E para obter resultados ainda melhores, use o pprint! python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
penguin359
20

você pode usar a __bases__tupla do objeto de classe:

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

A tupla retornada por __bases__possui todas as suas classes base.

Espero que ajude!

mandel
fonte
Se seus herda da classe de uma classe que herda de uma classe, apenas a primeira parte da cadeia estará em seu__bases__
Boris
Simples e limpo, sem importar um módulo inteiro para uma única função.
Temperosa 8/07
8

No python 3.7, você não precisa importar, inspecione, type.mro fornecerá o resultado.

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

atenção que no python 3.x toda classe herda da classe de objeto base.

Serjik
fonte
8

De acordo com o documento Python , também podemos simplesmente usar class.__mro__atributo ou class.mro()método:

>>> 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
YaOzI
fonte
2

Embora a resposta de Jochen seja muito útil e correta, como você pode obter a hierarquia de classes usando o método .getmro () do módulo inspecionar, também é importante destacar que a hierarquia de herança do Python é a seguinte:

ex:

class MyClass(YourClass):

Uma classe herdada

  • Classe criança
  • Classe derivada
  • Subclasse

ex:

class YourClass(Object):

Uma classe herdada

  • Classe pai
  • Classe base
  • Superclasse

Uma classe pode herdar de outra - A classe atribuída é herdada - em particular, seus métodos são herdados - isso significa que instâncias de uma classe herdada (filho) podem acessar atribuídas à classe herdada (pai)

instância -> classe -> classes herdadas

usando

import inspect
inspect.getmro(MyClass)

mostrará a hierarquia no Python.

Carson
fonte