Jak zdobyć rodziców klasy Python?


Odpowiedzi:


233

Użyj następującego atrybutu:

cls.__bases__

Z dokumentów :

Krotka klas podstawowych obiektu klasy.

Przykład:

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

Inny przykład:

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

1
Aby uzyskać podstawy obiektu instancji, wykonaj czynności type(C()).__bases__opisane poniżej
citynorman

106

Jeśli chcesz wszystkich przodków, a nie tylko bezpośrednich, użyj inspect.getmro :

import inspect
print inspect.getmro(cls)

Przydatnie, daje to wszystkie klasy przodków w „kolejności rozpoznawania metod” - tj. W kolejności, w której przodkowie będą sprawdzani podczas rozwiązywania metody (lub w rzeczywistości dowolnego innego atrybutu - metody i inne atrybuty żyją w tej samej przestrzeni nazw w końcu w Pythonie ;-).


34
Możesz także użyć cls.__mro__(przynajmniej w Pythonie 3.5)
naught101 16.01.17

@ naught101, plz zmień to w pełną odpowiedź. Prawie za tym tęskniłem i podobnie myślę, że wielu innych ludzi.
Shihab Shahriar Khan

14

Klasy w nowym stylu mają metodę mro, którą można wywołać, która zwraca listę klas nadrzędnych w kolejności rozwiązywania metod.


Co liczy się jako klasa w nowym stylu? Wydaje się, że mogę tego używać z modelami Django, ale objectwydaje się , że nic po prostu dziedziczącego po nie odpowiada mro.
Brian Kung,

1
rozważając obiekt x, możemy uzyskać kolejność rozwiązywania metod z wywołaniem, type(x).mro() które możemy rozważyć, jeśli xma ClassXjako klasę podstawową z: ClassX in type(x).mro()
648trindade

13

Najszybszy sposób, aby zobaczyć wszystkich rodziców i NA ZAMÓWIENIE , wystarczy użyć wbudowanego__mro__

to znaczy repr(YOUR_CLASS.__mro__)


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

wyjścia, W ZAMÓWIENIU


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

Masz to. „Najlepsza” odpowiedź ma teraz 182 głosy (jak to piszę), ale jest to TAK O wiele prostsze niż niektóre skomplikowane pętle, patrząc na podstawy jednej klasy na raz, nie wspominając o tym, kiedy klasa rozszerza DWA lub więcej rodziców zajęcia inspectNiepotrzebne importowanie i używanie tylko chmur powoduje, że zakres jest niepotrzebny. Szkoda, że ​​ludzie nie wiedzą, jak korzystać z wbudowanych funkcji

Mam nadzieję, że to pomoże!


@John Smith stackoverflow.com/users/139885/john-smith , mam nadzieję, że zobaczysz tę odpowiedź. Jeśli Ci się spodoba, daj mi znać z entuzjazmem!
PyTis

1
W rzeczywistości inspect.getmropo prostu wywołuje __mro__obiekt, jak widać na github.com/python/cpython/blob/… . Użycie getmrotworzy czystszy i bardziej czytelny kod. Chociaż pomijanie wywołania funkcji jest rzeczywiście szybsze.
tna0y

9

Użyj baz, jeśli chcesz tylko zdobyć rodziców, użyj __mro__(jak wskazał @ naught101), aby uzyskać kolejność rozwiązywania metod (aby wiedzieć, w jakiej kolejności zostały wykonane init).

Podstawy (i pierwsze uzyskanie klasy dla istniejącego obiektu):

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

W przypadku mro w najnowszych wersjach języka Python:

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

Oczywiście, gdy masz już definicję klasy, możesz po prostu wywołać __mro__ją bezpośrednio:

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

3

Jeśli chcesz mieć pewność, że wszystkie zostaną wywołane, użyj superna wszystkich poziomach.


Kiedy już użyjesz super, musisz użyć go na wszystkich poziomach, dlatego powinieneś udokumentować jego użycie jawnie. Możesz także chcieć wiedzieć, że super nie działa na każdej klasie ...
DasIch
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.