列出给定类的层次结构中的所有基类?


Answers:


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(path)文件“ /System/Library/Frameworks/Python.framework/在getmro searchbases (cls,结果)文件“ /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect”中的 Versions / 2.7 / lib / python2.7 / inspect.py”,第348行 py”为,线339,在_searchbases用于CLS .__ bases_基:AttributeError的: ' NSTaggedDate'对象没有属性'__bases '
RBP

17
@rbp我怀疑您遇到了与我相同的问题:您试图inspect.getmro(obj)代替inspect.getmro(type(obj))
esmit 2015年

44

请参阅python上的可用__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明确指出“在该元组中没有类出现多次”的原因?
Sridhar Ratnakumar,2009年

10
注意,__bases__只能上一层。(正如您的递归实用程序所暗示的那样,但是粗略地看一下示例可能无法理解这一点。)
Bob Stein

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

20

您可以使用__bases__类对象的元组:

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

返回的元组__bases__具有其所有基类。

希望能帮助到你!


如果您的课程继承自某个课程,而该课程又继承自该课程,则只有链的第一部分位于__bases__
Boris

简单而干净,无需为单个功能导入整个模块。
Temperosa

8

在python 3.7中,您无需导入inspect,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

尽管Jochen的回答非常有帮助和正确,但是您可以使用inspect模块的.getmro()方法获得类层次结构,但是突出显示Python的继承层次结构也很重要:

例如:

class MyClass(YourClass):

继承类

  • 儿童班
  • 派生类
  • 子类

例如:

class YourClass(Object):

继承的类

  • 家长班
  • 基类
  • 超类

一个类可以从另一个类继承-该类的属性是继承的-特别是其方法是继承的-这意味着继承(子)类的实例可以访问该继承(父)类的属性

实例->类->然后继承的类

使用

import inspect
inspect.getmro(MyClass)

将在Python中向您显示层次结构。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.