合并班级成员

时间:2017-06-29 21:32:08

标签: python python-3.x class

给出这样的类结构:

class A:
    dependencies = ["x", "y"]

class B(A):
    dependencies = ["z"]

class C(A):
    dependencies = ["n", "m"]

class D(C):
    dependencies = ["o"]

我想知道是否有可能编写一个函数(最好是生活在A类),这些函数可以按照以下方式执行:

@classmethod
def get_all_dependencies(cls):
    return super().get_all_dependencies() + cls.dependencies

对于上述类,预期输出为:

>>> A.get_all_dependencies():
["x", "y"]
>>> B.get_all_dependencies():
["x", "y", "z"]
>>> C.get_all_dependencies():
["x", "y", "n", "m"]
>>> D.get_all_dependencies():
["x", "y", "n", "m", "o"]

显然上面的代码不起作用 - 它只返回我调用它的类的dependencies。我不确定如何让它在所有类中递归工作? (我正在检查hasattr以确保父类调用get_all_dependencies()。)

3 个答案:

答案 0 :(得分:5)

mro并抓住依赖关系就是我要做的事情:

@classmethod
def get_dep(cls):
    return [d for c in cls.mro()[:-1] for d in getattr(c, 'dependencies')]

cls.mro()[:-1]用于排除object

返回:

>>> A.get_dep()
['x', 'y']
>>> B.get_dep()
['z', 'x', 'y']
>>> C.get_dep()
['n', 'm', 'x', 'y']
>>> D.get_dep()
['o', 'n', 'm', 'x', 'y']

答案 1 :(得分:4)

手动走MRO:

@classmethod
def get_all_dependencies(cls):
    deps = []
    for c in cls.__mro__:
        # Manual dict lookup to not pick up inherited attributes
        deps += c.__dict__.get('dependencies', [])
    return deps

如果要对MRO中重复出现的依赖项进行重复数据删除,您可以:

from collections import OrderedDict

@classmethod
def get_all_dependencies(cls):
    return list(OrderedDict.fromkeys(dep for c in cls.__mro__
                                         for dep in c.__dict__.get('dependencies', [])))

答案 2 :(得分:0)

如果你在每个类上定义“get_all_dependencies”,你肯定可以这样做,而不是cls.dependencies,你引用你所在的类(即super(B, self).get_all_dependences() + B.dependencies