Как получить родителей класса Python?

202

Как я могу получить родительский класс (ы) класса 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, пожалуйста, включите полный ответ. Я почти пропустил это, и я думаю, что многие другие люди тоже.
Шихаб Шахриар Хан
14

У классов нового стиля есть метод mro, который вы можете вызвать, который возвращает список родительских классов в порядке разрешения методов.

DasIch
источник
Что считается классом нового стиля? Кажется, я могу использовать это с моделями 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Излишне только облака. Честно говоря, это позор, люди не знают, просто использовать встроенные модули

Надеюсь, это поможет!

PyTis
источник
@ Джон Смит stackoverflow.com/users/139885/john-smith , я надеюсь, что вы видите этот ответ. Если вам это нравится, пожалуйста, дайте мне знать с upvote!
PyTis
1
На самом деле, inspect.getmroпросто вызывает __mro__объект, как вы можете видеть в github.com/python/cpython/blob/… . Использование getmroдает более чистый и читаемый код. Хотя пропуск вызова функции действительно быстрее.
19
9

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

Основы (и сначала получение класса для существующего объекта):

>>> 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)
PascalVKooten
источник
3

Если вы хотите, чтобы все они были вызваны, используйте superна всех уровнях.

Майк Грэм
источник
Как только вы используете super, вы все равно должны использовать его на всех уровнях, поэтому вам следует задокументировать, что вы используете его явно. Кроме того, вы можете знать, что супер не работает на каждом классе ...
DasIch