代码之家  ›  专栏  ›  技术社区  ›  jelovirt

Python超类反射

  •  31
  • jelovirt  · 技术社区  · 17 年前

    如果我有Python代码

    class A():
        pass
    class B():
        pass
    class C(A, B):
        pass
    

    我还有课 C ,是否有一种方法可以遍历它的超级类( A B )? 类似于伪代码:

    >>> magicGetSuperClasses(C)
    (<type 'A'>, <type 'B'>)
    

    一个解决办法似乎是 inspect module getclasstree 作用

    def magicGetSuperClasses(cls):
        return [o[0] for o in inspect.getclasstree([cls]) if type(o[0]) == type]
    

    但这是实现目标的“蟒蛇式”方法吗?

    4 回复  |  直到 17 年前
        1
  •  37
  •   Ethan Furman    14 年前

    C.__bases__ 是一个超类数组,所以您可以像这样实现假设的函数:

    def magicGetSuperClasses(cls):
      return cls.__bases__
    

    但我想只参考一下会更容易些 cls.__bases__

        2
  •  11
  •   cdleary    17 年前

    @约翰:你的代码片段不起作用——你正在返回 cls.__bases__

    class A: pass
    class B: pass
    class C(A, B): pass
    
    c = C() # Instance
    
    assert C.__bases__ == (A, B) # Works
    assert c.__class__.__bases__ == (A, B) # Works
    
    def magicGetSuperClasses(clz):
      return tuple([base.__class__ for base in clz.__bases__])
    
    assert magicGetSuperClasses(C) == (A, B) # Fails
    

    另外,如果您使用的是Python2.4+,那么可以使用 generator expressions tuple )。例如:

    def get_base_metaclasses(cls):
        """Returns the metaclass of all the base classes of cls."""
        return tuple(base.__class__ for base in clz.__bases__)
    

    这是一个有点令人困惑的例子,但genexps通常都很简单和酷

        3
  •  4
  •   Torsten Marek    17 年前

    检查模块启动良好,请使用 getmro 功能:

    以方法解析顺序返回类clss基类(包括cls)的元组。没有类在此元组中出现多次。。。

    >>> class A: pass
    >>> class B: pass
    >>> class C(A, B): pass
    >>> import inspect
    >>> inspect.getmro(C)[1:]
    (<class __main__.A at 0x8c59f2c>, <class __main__.B at 0x8c59f5c>)
    

    返回的元组的第一个元素是 C ,你可以忽略它。

        4
  •  2
  •   sinzi    17 年前

    如果您需要知道super()调用可以使用的类的顺序 C.__mro__ 而且不需要 inspect 因此