透過遞迴查詢應用依賴

昀溪發表於2018-08-18

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處迴圈呼叫,如果你不控制,那麼遞迴到最深一層就會報錯,而結果也不是我們想要的。所以必須控制迴圈呼叫的這種情況。

 

相關文章