【问题标题】:How can I work out the class hierarchy given an object instance in Python?给定 Python 中的对象实例,如何计算出类层次结构?
【发布时间】:2009-10-21 22:11:59
【问题描述】:

有没有办法在 Python 中发现一个类的基类?

对于给定的以下类定义:

class A:
   def speak(self):
      print "Hi"

class B(A):
   def getName(self):
      return "Bob"

如果我收到一个对象的实例,我可以通过执行以下操作轻松确定它是 B:

instance = B()
print B.__class__.__name__

按预期打印类名“B”。

有没有发现对象的实例继承自基类以及实际类?

或者这不是 Python 中对象的工作方式?

【问题讨论】:

    标签: python inheritance oop


    【解决方案1】:

    inspect 模块也很强大:

    >>> import inspect
    
    >>> inst = B()
    >>> inspect.getmro(inst.__class__)
    (<class __main__.B at 0x012B42A0>, <class __main__.A at 0x012B4210>)
    

    【讨论】:

      【解决方案2】:
      b = B()
      b.__class__
      b.__class__.__base__
      b.__class__.__bases__
      b.__class__.__base__.__subclasses__()
      

      我强烈建议检查 ipython 并使用制表符完成 :-)

      【讨论】:

      • 有趣的是,ipython 没有看到 bases,但评估它是可以的。我猜 base 在 2.5 中不存在,因为这对我没有好处。
      • 在真正使用接近 Python 核心功能的接口时,我会密切关注特定于版本的 Python 文档。这应该让您了解是否首选 basebasesdocs.python.org/library/stdtypes.html 只谈论 bases
      • 哦,我正在运行 Python 2.6(作为记录)。
      【解决方案3】:

      获取类层次结构的另一种方法是访问 mro 属性:

      class A(object):
          pass
      class B(A):
          pass
      instance = B()
      print(instance.__class__.__mro__)
      # (<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
      

      请注意,在 Python 2.x 中,您必须使用“新样式”对象以确保它们具有 mro 属性。你可以通过声明

      class A(object):
      

      而不是

      class A():
      

      请参阅http://www.python.org/doc/newstyle/http://www.python.org/download/releases/2.3/mro/ 了解更多关于新型对象和mro(方法解析顺序)的信息。

      在 Python 3.x 中,所有对象都是新式对象,因此您可以使用 mro 并以这种方式简单地声明对象:

      class A():
      

      【讨论】:

        【解决方案4】:

        如果您事先知道所需的类而不是发现基类(即反射),则可以使用以下built in functions

        例如:

        # With classes from original Question defined
        >>> instance = A()
        >>> B_instance = B()
        >>> isinstance(instance, A)
        True
        >>> isinstance(instance, B)
        False
        >>> isinstance(B_instance, A) # Note it returns true if instance is a subclass
        True
        >>> isinstance(B_instance, B)
        True
        >>> issubclass(B, A)
        True
        

        isinstance(对象,类信息) 如果 object 参数是 classinfo 的实例,则返回 true 论点,或(直接或间接) 其子类。如果也返回 true classinfo 是一个类型对象和对象 是该类型的对象。如果对象 不是类实例或对象 给定类型的,函数总是 返回假。如果 classinfo 既不是 一个类对象也不是一个类型对象,它 可能是类或类型的元组 对象,或者可能递归地包含 其他这样的元组(其他序列 不接受类型)。如果类信息 不是一个类、类型或元组 类、类型和这样的元组,a 引发 TypeError 异常。改变了 在 2.2 版中:支持元组 添加了类型信息。

        issubclass(class, classinfo) 如果 class 是 classinfo 的子类(直接或间接),则返回 true。一个 类被认为是 本身。 classinfo 可能是一个元组 类对象,在这种情况下,每个 将检查 classinfo 中的条目。在 任何其他情况,TypeError 异常 被提出。在 2.3 版中更改: 支持类型的元组 已添加信息。

        【讨论】:

          猜你喜欢
          • 2021-08-06
          • 2012-04-04
          • 1970-01-01
          • 1970-01-01
          • 2021-09-11
          • 2013-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多