Aqui está como você pode encontrar uma lista de dependências de classes Python, desde que uma classe tenha um
atributo depends
. Esta lista não é classificada topologicamente, mas é muito fácil de usar com um algoritmo de classificação topológica.
Usando recursão e gerador é possível obter uma lista completa de dependências, dado que
start_dependecie = {'A': 'B'}
Isso significa que class A
depende class B
. Mas e se class B
depender de N outras classes?
O seguinte fará o trabalho:
#!/usr/bin/env python
def _yield_name_dep(rules_deps):
# yield all rules by their name and dependencies
for rule, dep in rules_deps.items():
if not dep:
yield rule, dep
continue
else:
yield rule, dep
for ii in dep:
i = getattr(rules, ii)
instance = i()
if instance.depends:
new_dep={str(instance): instance.depends}
for dep in _yield_name_dep(new_dep):
yield dep
else:
yield str(instance), instance.depends
Veja como você pode testar facilmente o método acima:
demo_class_content ="""
class A(object):
depends = 'B'
def __str__(self):
return self.__class__.__name__
class B(object):
depends = ('C','F')
def __str__(self):
return self.__class__.__name__
class C(object):
depends = ('D', 'E')
def __str__(self):
return self.__class__.__name__
class D(object):
depends = None
def __str__(self):
return self.__class__.__name__
class F(object):
depends = 'E'
def __str__(self):
return self.__class__.__name__
class E(object):
depends = None
def __str__(self):
return self.__class__.__name__
"""
with open('demo_classes.py', 'w') as clsdemo:
clsdemo.write(demo_class_content)
import demo_classes as rules
rule_start={'A': 'B'}
recursion_counter = 0
def _yield_name_dep(rules_deps):
global recursion_counter
recursion_counter = recursion_counter +1
# yield all rules by their named and dependencies
for rule, dep in rules_deps.items():
if not dep:
yield rule, dep
continue
else:
yield rule, dep
for ii in dep:
i = getattr(rules, ii)
instance = i()
if instance.depends:
new_dep={str(instance): instance.depends}
for dep in _yield_name_dep(new_dep):
yield dep
else:
yield str(instance), instance.depends
if __name__ == '__main__':
rule_dependencies = list(set(_yield_name_dep(rule_start)))
print recursion_counter
print rule_dependencies
A saída deve ser:
4
[('B', ('C', 'F')), ('C', ('D', 'E')), ('E', None), ('F', 'E'), ('D', None), ('A', 'B')]