如何通过继承深度对Python类列表进行排序?

时间:2014-05-14 16:40:07

标签: python class oop method-resolution-order

如何在Python中对类列表进行排序,确保任何子类都在列表中的任何父类之前?

我问,因为我想查看一个类型列表中的类型,一个对象属于哪个类型,但是如果它属于多个类型,则查找最具体的类型。

2 个答案:

答案 0 :(得分:8)

只需按len(cls.mro())排序。

如果C2C1的子类,则必须保留len(C1.mro()) < len(C2.mro())(因为C1.mro()中的每个类也必须出现在C2.mro()中)。因此,您只需按mro list

的长度排序即可
class A(object): pass
class X(object): pass
class B(A, X): pass
class C(B): pass
class D(C): pass

sorted([B, C, A, D, X], key = lambda cls: len(cls.mro()))
=> [__main__.A, __main__.X, __main__.B, __main__.C, __main__.D]

要同时支持旧式课程,您可以将cls.mro()替换为inspect.getmro(cls)

答案 1 :(得分:0)

更好的方法是使用集合,然后沿目标类的继承树移动。

def find_parent(target, class_set):
    if target in class_set:
        return [target]
    else:
        bases = []
        for parent in target.__bases__:
            result = find_parent(parent, class_set)
            if result is not None:
                bases.extend(result)
        return bases

示例:

class A(object):
    pass

class B(str):
    pass

class C(A):
    pass

class D(A, dict):
    pass

class_set = {dict, A}

print find_parent(A, class_set)
print find_parent(B, class_set)
print find_parent(C, class_set)
print find_parent(D, class_set)

给你这个结果:

[<class '__main__.A'>]
[]
[<class '__main__.A'>]
[<class '__main__.A'>, <type 'dict'>]