Python中的类继承

5

我是Python的新手,正在尝试获取一个对象所继承的类列表。我正在尝试使用bases属性来实现这一点,但是我没有成功。请有人帮帮我吗?

def foo(C):
     print(list(C.__bases__))

class Thing(object):
    def f(self):
        print("Yo")

class Shape(Thing):
    def l(self):
        print("ain't no thang")

class Circle(Shape):
    def n(self):
        print("ain't no shape")

test = Circle()
foo(test)
4个回答

6

只有类才有__bases__属性,类的实例没有此属性。您可以通过实例的__class__获取该类对象:使用foo(test.__class__)foo(Circle)


4

使用文档中的inspect方法。

以方法解析顺序返回类cls及其基类的元组,包括cls。在此元组中,每个类只出现一次。请注意,方法解析顺序取决于cls的类型。除非使用了非常奇特的用户定义元类型,否则cls将是元组的第一个元素。

>>> import inspect
>>> inspect.getmro(test.__class__)
(<class '__main__.Circle'>, <class '__main__.Shape'>, <class '__main__.Thing'>, <type 'object'>)
>>> 

这会遍历继承层次结构并打印所有类,包括object。很酷吧?


+1 是因为它返回所有类的列表。为了使它适用于 OP 的示例,我认为应该是 test.__class__,因为在他的情况下,test 是一个实例? - RocketDonkey
是的,应该是 test.__class__,我匆忙回答了 :) - Srikar Appalaraju
假设这是一个新式类,test.__class__.__mro__ 也应该可以工作。使用 getmro 的原因是它同样处理旧式类。它首先查找 __mro__,如果没有找到,则假定该类是旧式类,并递归搜索 __bases__ 层次结构。如果您不需要该功能,则可以避免导入。 - senderle
是的,我忘记了那个,谢谢你指出来。但我的哲学是,当核心库中有一个方法可以做到这一点(并且还提供向后兼容性),为什么要编写自己的方法呢? - Srikar Appalaraju
我明白你的意思 - 当然,你是对的,导入getmro比上面定义foo更有意义。 - senderle

2
print '\n'.join(base.__name__ for base in test.__class__.__bases__)

或者,使用inspect模块:
from inspect import getmro
print '\n'.join(base.__name__ for base in getmro(test))

1

你的 foo 实现是有效的。但是你需要传递一个类给 foo,而不是一个实例。

In [1]: def foo(C):
   ...:          print(list(C.__bases__))
   ...:

In [2]: class Thing(object):
   ...:         def f(self):
   ...:                 print("Yo")
   ...:

In [3]: class Shape(Thing):
   ...:         def l(self):
   ...:                 print("ain't no thang")
   ...:

In [4]: class Circle(Shape):
   ...:         def n(self):
   ...:                 print("ain't no shape")
   ...:

In [5]: test = Circle()

In [6]: foo(test)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-6-7b85deb1beaa> in <module>()
----> 1 foo(test)

<ipython-input-1-acd1789d43a9> in foo(C)
      1 def foo(C):
----> 2          print(list(C.__bases__))
      3

AttributeError: 'Circle' object has no attribute '__bases__'

In [7]: foo(Thing)
[<type 'object'>]

In [8]: foo(Circle)
[<class '__main__.Shape'>]

In [9]: foo(Shape)
[<class '__main__.Thing'>]

啊,谢谢大家。非常感谢。我之前不明白对象没有基础。 - Alex Winchell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接