Python递归网上的例子很多大多是数学计算,我在工作遇到一个问题也需要递归来解决但是稍有不同,我们生产环境使用Dubbo分布式服务,Dubbo monitor可以显示应用的调用关系,但是现实情况是随着时间推移应用增多功能增多就会发生循环调用的情况,比如应用A的生产者是由应用A的消费者调用,这就是自己调用自己,还有的是隔了几级由调用回来了。看下图
现在的要求就是给定一个应用找出它直接和间接依赖的所有应用,相同的保留一个(这个相同指的是,A依赖B,B依赖E,E也依赖E,如果指定A,则返回B和E)
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys dic1 = { 'A': ['B', 'C', 'D', 'F'], 'B': ['E'], 'C': [], 'D': ['F'], 'E': ['E'], 'F': ['B', 'D'] } # 保存结果的列表 list1 = [] def findApp(name): # 这里判断如果该应用谁也不依赖就直接返回None,不依赖别人说明自己是一个基础服务,属于被调用方。 if len(dic1[name]) == 0: return None else: # 遍历给定应用的直接依赖应用 for i in dic1[name]: # 这里判断是否已经添加到结果列表里,作用是不重复添加,其实这里最大的作用就是为了避免循环调用产生的无穷无尽 if i in list1: continue # 如果结果列表中没有就添加进来 list1.append(i) # 调用自己把i传递进去找i这个应用的下一级,如此反复 findApp(i) def main(): # A 应用期望的输出为 B C D F E try: findApp('A') except Exception as err: print err.message print set(list1) if __name__ == "__main__": try: main() finally: sys.exit()
其实大家可以自己看一下A里面存在2处循环调用,如果你不控制,那么递归到最深一层就会报错,而结果也不是我们想要的。所以必须控制循环调用的这种情况。