Como obter os pais de uma classe Python?


202

Como posso obter as classes pai de uma classe Python?

Respostas:


233

Use o seguinte atributo:

cls.__bases__

Dos documentos :

A tupla de classes base de um objeto de classe.

Exemplo:

>>> str.__bases__
(<type 'basestring'>,)

Outro exemplo:

>>> class A(object):
...   pass
... 
>>> class B(object):
...   pass
... 
>>> class C(A, B):
...   pass
... 
>>> C.__bases__
(<class '__main__.A'>, <class '__main__.B'>)

1
Para obter bases de um objeto instanciado, faça type(C()).__bases__o mencionado abaixo
— citynorman

106

Se você deseja todos os ancestrais, e não apenas os ancestrais , use inspect.getmro :

import inspect
print inspect.getmro(cls)

De maneira útil, isso fornece a você todas as classes de ancestrais na "ordem de resolução do método" - isto é, a ordem na qual os ancestrais serão verificados ao resolver um método (ou, na verdade, qualquer outro atributo - métodos e outros atributos vivem no mesmo espaço de nome) afinal, em Python ;-).


34
Você também pode apenas usar cls.__mro__(pelo menos em Python 3.5)
— naught101

@ naught101, plz transformá-lo em uma resposta completa. Eu quase senti falta e acho que muitas outras pessoas.
— Shihab Shahriar Khan

14

As classes de novo estilo têm um método mro que você pode chamar, que retorna uma lista de classes pai na ordem de resolução do método.


O que conta como uma classe de novo estilo? Parece que posso usar isso com os modelos do Django, mas qualquer coisa simplesmente herdada objectnão parece responder mro.
— Brian Kung

1
considerando um objeto x, podemos obter a ordem de resolução do método com a chamada type(x).mro() que podemos considerar se xtiver ClassXcomo classe base: ClassX in type(x).mro()
— 648trindade

13

A maneira MAIS RÁPIDA , para ver todos os pais, e EM ORDEM , basta usar o__mro__

ie repr(YOUR_CLASS.__mro__)


>>>
>>>
>>> import getpass
>>> getpass.GetPassWarning.__mro__

saídas, EM ORDEM


(<class 'getpass.GetPassWarning'>, <type 'exceptions.UserWarning'>,
<type 'exceptions.Warning'>, <type 'exceptions.Exception'>, 
<type 'exceptions.BaseException'>, <type 'object'>)
>>>

Aí está. A "melhor" resposta no momento tem 182 votos (enquanto digito isso), mas isso é MUITO mais simples do que um loop for complicado, procurando nas bases uma classe de cada vez, sem mencionar quando uma classe estende DOIS ou mais pais Aulas. Importando e usandoinspect apenas obscurece o escopo desnecessariamente. Sinceramente, é uma pena que as pessoas não saibam usar apenas os embutidos

Eu espero que isso ajude!


@John Smith stackoverflow.com/users/139885/john-smith , espero que você veja esta resposta. Se você gostou, por favor me avise com um voto positivo!
— PyTis 26/03/19

1
De fato, inspect.getmrobasta chamar o __mro__objeto, como você pode ver em github.com/python/cpython/blob/… . Usar getmroproduz código mais limpo e mais legível. Embora pular uma chamada de função seja realmente mais rápido.
— tna0y

9

Use bases se você quiser apenas obter os pais, use __mro__(como indicado por @ naught101) para obter a ordem de resolução do método (para saber em qual ordem os init foram executados).

Bases (e primeiro obtendo a classe para um objeto existente):

>>> some_object = "some_text"
>>> some_object.__class__.__bases__
(object,)

Para mro nas versões recentes do Python:

>>> some_object = "some_text"
>>> some_object.__class__.__mro__
(str, object)

Obviamente, quando você já tem uma definição de classe, basta acessar __mro__diretamente:

>>> class A(): pass
>>> A.__mro__
(__main__.A, object)

3

Se você quiser garantir que todos sejam chamados, use superem todos os níveis.


Depois de usar o super, você deve usá-lo em todos os níveis, e é por isso que você deve documentar seu uso explicitamente. Além disso, você pode querer saber que o super não funciona em todas as classes ...
— DasIch
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.