Перерахуйте всі базові класи в ієрархії даного класу?


Відповіді:


196

inspect.getmro(cls)працює як для нових, так і для старих класів стилів і повертає те саме, що NewClass.mro(): список класу та всі його класи предків у порядку, що використовується для вирішення методу.

>>> class A(object):
>>>     pass
>>>
>>> class B(A):
>>>     pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)

2
Не працює для класів pyobjc :( Файл "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", рядок 70, у файлі примусового друку Inspect.getmro (шлях) Файл "/System/Library/Frameworks/Python.framework/ Версії / 2.7 / lib / python2.7 / inspect.py ", рядок 348, у пошукових базах getmro (cls, результат) Файл" /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect .py ", рядок 339, в _searchbases для бази в cls .__ bases_ : AttributeError: ' NSTaggedDate' об'єкт не має атрибута '__bases '
rbp

17
@rbp Я підозрюю, що у вас була та сама проблема, з якою я стикався: ви намагалися зробити це inspect.getmro(obj)замість inspect.getmro(type(obj)).
емітувати

44

Перегляньте __bases__властивість, доступну на пітоні class, який містить кортеж базових класів:

>>> 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>]

5
Це може ввести дублікати. І саме тому в документації getmroпрямо написано "Жоден клас не відображається більше ніж один раз у цьому кортежі"?
Шрідхар Ратнакумар

10
Обережно, __bases__піднімається лише на один рівень . (Як випливає з вашої рекурсивної утиліти, але побіжний погляд на приклад може не сприймати цього.)
Боб Штейн

32

inspect.getclasstree()створить вкладений список класів та їх бази. Використання:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.

1
О, приємно. А для ще кращого виходу використовуйте pprint! python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
penguin359

20

ви можете використовувати __bases__кортеж об’єкта класу:

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

Кортеж, що повертається, __bases__має всі його базові класи.

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


Якщо ваш клас успадковує від класу, який успадковує від класу, лише перша частина ланцюга буде в ньому__bases__
Борис

Простий і чистий без імпорту цілого модуля для однієї функції.
Темпераса

8

У python 3.7 вам не потрібно імпортувати перевірку, type.mro дасть результат.

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

увагу, що в python 3.x кожен клас успадковує від базового класу об'єктів.


8

Згідно з документом Python , ми також можемо просто використовувати class.__mro__атрибут або class.mro()метод:

>>> 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

2

Хоча відповідь Йохана дуже корисна і правильна, оскільки ви можете отримати ієрархію класів за допомогою методу .getmro () модуля перевірки, також важливо підкреслити, що ієрархія спадкування Python полягає в наступному:

колишній:

class MyClass(YourClass):

Клас успадкування

  • Дитячий клас
  • Отриманий клас
  • Підклас

колишній:

class YourClass(Object):

Спадковий клас

  • Батьківський клас
  • Базовий клас
  • Суперклас

Один клас може успадковувати інший - атрибутові класу передаються у спадок - зокрема, його методи успадковуються - це означає, що екземпляри спадкового (дочірнього) класу можуть отримати доступ до атрибутованого спадкового (батьківського) класу

екземпляр -> клас -> потім успадковані класи

використовуючи

import inspect
inspect.getmro(MyClass)

покаже вам ієрархію в Python.

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