Як отримати батьків класу Python?


Відповіді:


233

Використовуйте такий атрибут:

cls.__bases__

З документів :

Збір базових класів об’єкта класу.

Приклад:

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

Ще один приклад:

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

1
Щоб отримати основи створеного об'єкта, виконайте, type(C()).__bases__як було сказано далі
citynorman

106

Якщо ви хочете всіх предків, а не лише безпосередніх, скористайтеся inspect.getmro :

import inspect
print inspect.getmro(cls)

Корисно, це дає вам всі класи предків у "порядку розв'язання методу" - тобто порядку, в якому перевірятимуться предки при вирішенні методу (або, власне, будь-якого іншого атрибута - методи та інші атрибути живуть в одному просторі імен в Python, зрештою ;-).


34
Ви також можете просто скористатися cls.__mro__(принаймні, в Python 3.5)
naught101

@ naught101, plz перетворять це на повну відповідь. Я майже пропустив це, і так буде, я думаю, що багато інших людей.
Шихаб Шахріар Хан

14

Класи нового стилю мають метод mro, до якого можна викликати, який повертає список батьківських класів у порядку роздільної здатності методу.


Що вважається класом нового стилю? Здається, я можу використовувати це з моделями Django, але все, що просто успадковується object, не здається mro.
Брайан Кунг

1
розглядаючи об’єкт x, ми можемо отримати порядок вирішення методу з викликом, який type(x).mro() ми можемо вважати, якщо він xмає ClassXв якості базового класу: ClassX in type(x).mro()
648trindade

13

ШВИДКИЙ шлях, щоб побачити всіх батьків, і ТОГО , просто використовуйте вбудований__mro__

тобто repr(YOUR_CLASS.__mro__)


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

Виходи, В ЗАМОВЛЕННІ


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

Там у вас є. "Найкращий" відповідь зараз має 182 голоси (як я це набираю), але це ТАК набагато простіше, ніж деякі згорнуті для циклу, дивлячись на бази один клас за один раз, не кажучи вже про те, коли клас поширюється ДВА і більше батьків заняття. Імпорт та використання inspectпросто хмарних областей без потреби. Чесно кажучи, прикро, що люди не знають просто використовувати вбудовані модулі

Я сподіваюся, що це допомагає!


@John Сміт stackoverflow.com/users/139885/john-smith , я сподіваюся , ви маєте доступ до цього відповідь. Якщо вам це подобається, будь ласка, повідомте мене про це!
PyTis

1
Насправді, inspect.getmroлише дзвінки __mro__на об’єкт, як ви бачите на github.com/python/cpython/blob/… . Використання getmroстворює більш чистий і читабельний код. Хоча пропуск виклику функції дійсно швидше.
tna0y

9

Використовуйте бази, якщо ви просто хочете отримати батьків, використовуйте __mro__(як вказувало @ naught101) для отримання порядку вирішення методу (щоб знати, в якому порядку виконувались init).

Основи (і перше отримання класу для існуючого об'єкта):

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

Для mro в останніх версіях Python:

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

Очевидно, коли у вас вже є визначення класу, ви можете просто зателефонувати __mro__на це безпосередньо:

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

3

Якщо ви хочете переконатися, що всі вони дзвонять, використовуйте superвсі рівні.


Після використання супер ви все одно повинні використовувати його на всіх рівнях, саме тому ви повинні документувати його використання явно. Також ви, можливо, захочете знати, що супер працює не на кожному класі ...
DasIch
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.