给出这样的类结构:
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()
。)
答案 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
)