欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Python3實現(xiàn)判斷函數(shù)的圈復(fù)雜度

 更新時間:2024年04月25日 11:11:40   作者:rs勿忘初心  
編寫函數(shù)最重要的原則就是:別寫太復(fù)雜的函數(shù),那什么樣的函數(shù)才能算是過于復(fù)雜?一般會通過兩個標(biāo)準(zhǔn)來判斷,長度和圈復(fù)雜度,下面我們就來看看如何使用Python判斷函數(shù)的圈復(fù)雜度吧

你有沒有見過那種長達(dá)幾百行、邏輯錯綜復(fù)雜的“巨無霸”函數(shù)?那樣的函數(shù)不光難讀,改起來同樣困難重重,人人唯恐避之不及。

編寫函數(shù)最重要的原則就是:別寫太復(fù)雜的函數(shù)。那什么樣的函數(shù)才能算是過于復(fù)雜?一般會通過兩個標(biāo)準(zhǔn)來判斷,長度和圈復(fù)雜度。

長度

長度也就是函數(shù)有多少行代碼。不過不能武斷地說,長函數(shù)就一定比短函數(shù)復(fù)雜。因為在不同的編程風(fēng)格下,相同行數(shù)的代碼所實現(xiàn)的功能可以有巨大差別,有人甚至能把一個完整的俄羅斯方塊游戲塞進(jìn)一行代碼內(nèi)。

但即便如此,長度對于判斷函數(shù)復(fù)雜度來說仍然有巨大價值。在著作《代碼大全(第 2 版)》中,Steve McConnell 提到函數(shù)的理想長度范圍是 65 到 200 行,一旦超過 200 行,代碼出現(xiàn) bug 的概率就會顯著增加。

對于 Python 這種強表現(xiàn)力的語言來說,65 行已經(jīng)非常值得警惕了。假如你的函數(shù)超過 65 行,很大概率代表函數(shù)已經(jīng)過于復(fù)雜,承擔(dān)了太多職責(zé),請考慮將它拆分為多個小而簡單的子函數(shù)(類)吧。

圈復(fù)雜度

“圈復(fù)雜度”是由 Thomas J. McCabe 在 1976 年提出的用于評估函數(shù)復(fù)雜度的指標(biāo)。它的值是一個正整數(shù),代表程序內(nèi)線性獨立路徑的數(shù)量。圈復(fù)雜度的值越大,表示程序可能的執(zhí)行路徑就越多,邏輯就越復(fù)雜。

如果某個函數(shù)的圈復(fù)雜度超過10,就代表它已經(jīng)太復(fù)雜了,代碼編寫者應(yīng)該想辦法簡化。優(yōu)化寫法或者拆分成子函數(shù)都是不錯的選擇。接下來,我們通過實際代碼來體驗一下圈復(fù)雜度的計算過程。

在Python中,可以通過radon工具計算函數(shù)的圈復(fù)雜度。安裝命令:

pip3 install radon

假設(shè)我們有段代碼示例如下,實現(xiàn)的功能是猜數(shù)字游戲,里面有1個whilie和2個if-else分支判斷邏輯,文件名:complex_func.py。

import random
 
def guess_number():
    # 生成一個隨機數(shù)作為答案
    answer = random.randint(1, 100)
 
    # 初始化猜測次數(shù)
    guesses = 0
 
    print("歡迎來到猜數(shù)字游戲!我已經(jīng)想好了一個1到100之間的數(shù)字,你需要猜出這個數(shù)字是多少。")
 
    # 開始循環(huán),直到玩家猜中數(shù)字為止
    while True:
        # 獲取玩家的猜測
        guess = int(input("請輸入你猜測的數(shù)字:"))
 
        # 增加猜測次數(shù)
        guesses += 1
 
        # 檢查玩家猜測的數(shù)字與答案的關(guān)系
        if guess < answer:
            print("你猜的數(shù)字太小了,請繼續(xù)努力!")
        elif guess > answer:
            print("你猜的數(shù)字太大了,請再試一次!")
        else:
            print(f"恭喜你,你猜對了!答案是 {answer}。你一共猜了 {guesses} 次。")
            break  # 結(jié)束循環(huán)
 
 
# 調(diào)用函數(shù)開始游戲
guess_number()

接下來我們使用radon來計算這個文件對應(yīng)函數(shù)的圈復(fù)雜度,文件名:calculate_cyclomatic_complexity.py

from radon.complexity import cc_visit
 
# 定義一個Python文件路徑
file_path = 'complex_func.py'
 
# 使用cc_visit函數(shù)計算代碼的圈復(fù)雜度
with open(file_path, 'r') as file:
    code = file.read()
    results = cc_visit(code)
    print(results)
 
# 打印結(jié)果
for result in results:
    print(result)

執(zhí)行結(jié)果:可以看到函數(shù)圈復(fù)雜度為 4。

$ python3 calculate_cyclomatic_complexity.py 
[Function(name='guess_number', lineno=3, col_offset=0, endline=27, is_method=False, classname=None, closures=[], complexity=4)]
F 3:0->27 guess_number - 4

我們接下來看另外一個完整的代碼示例,其中被計算的函數(shù)為rank(),功能是按照電影分?jǐn)?shù)計算評級,最后輸出了圈復(fù)雜度和對應(yīng)的評分等級,文件名:

get_film_score.py

import radon
from radon.complexity import cc_rank, cc_visit
 
 
def calculate_complexity(source_code):
    """
    Calculate the cyclomatic complexity of the given source code.
    Parameters:
    source_code (str): The source code to analyze.
    Returns:
    int: The cyclomatic complexity.
    str: The complexity rating.
    """
    try:
        # Visit the AST and calculate the complexity
        results = cc_visit(source_code)
        complexity = results[0].complexity
        # Get the complexity rating
        rating = cc_rank(complexity)
        return complexity, rating
    except Exception as e:
        print("Error:", e)
        return None, None
 
 
# Example usage:
if __name__ == "__main__":
    code = """
def rank(self):
    rating_num = float(self.rating)
    if rating_num >= 8.5:
        return 'S'
    elif rating_num >= 8:
        return 'A'
    elif rating_num >= 7:
        return 'B'
    elif rating_num >= 6:
        return 'C'
    else:
        return 'D'
    """
    complexity, rating = calculate_complexity(code)
    if complexity is not None and rating is not None:
        print("Cyclomatic Complexity:", complexity)
        print("Complexity Rating:", rating)

運行結(jié)果:可以看到函數(shù)圈復(fù)雜度為 5,評級為 A。

雖然這個值沒有達(dá)到危險線 10,但考慮到函數(shù)只有短短 10 行,5 已經(jīng)足夠引起重視了。

$ python3 get_film_score.py
Cyclomatic Complexity: 5
Complexity Rating: A

作為對比,我們再計算一下案例中使用bisect模塊重構(gòu)后的 rank() 函數(shù):

def rank(self):
    breakpoints = (6, 7, 8, 8.5)
    grades = ('D', 'C', 'B', 'A', 'S')
    index = bisect.bisect(breakpoints, float(self.rating))
    return grades[index]

運行結(jié)果:可以看到函數(shù)圈復(fù)雜度為 1,評級為 A。

$ python3 get_film_score.py
Cyclomatic Complexity: 1
Complexity Rating: A

可以看到,新函數(shù)的圈復(fù)雜度從 5 降至 1。1 是一個非常理想化的值,如果一個函數(shù)的圈復(fù)雜度為 1,就代表這個函數(shù)只有一條主路徑,沒有任何其他執(zhí)行路徑,這樣的函數(shù)通常來說都十分簡單、容易維護(hù)。

當(dāng)然,在正常的項目開發(fā)流程中,我們一般不會在每次寫完代碼后,都手動執(zhí)行一次 radon 命令檢查函數(shù)圈復(fù)雜度是否符合標(biāo)準(zhǔn),而會將這種檢查配置到開發(fā)或部署流程中自動執(zhí)行。

到此這篇關(guān)于使用Python3實現(xiàn)判斷函數(shù)的圈復(fù)雜度的文章就介紹到這了,更多相關(guān)Python3函數(shù)圈復(fù)雜度內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python實現(xiàn)提取百度搜索結(jié)果的方法

    python實現(xiàn)提取百度搜索結(jié)果的方法

    這篇文章主要介紹了python實現(xiàn)提取百度搜索結(jié)果的方法,涉及Python網(wǎng)頁及字符串操作的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • Python中線程的MQ消息隊列實現(xiàn)以及消息隊列的優(yōu)點解析

    Python中線程的MQ消息隊列實現(xiàn)以及消息隊列的優(yōu)點解析

    消息隊列(MQ,Message Queue)在消息數(shù)據(jù)傳輸中的保存作用為數(shù)據(jù)通信提供了保障和實時處理上的便利,這里我們就來看一下Python中線程的MQ消息隊列實現(xiàn)以及消息隊列的優(yōu)點解析
    2016-06-06
  • Python FastAPI入門安裝使用

    Python FastAPI入門安裝使用

    FastAPI是一個現(xiàn)代、快速的Python Web框架,用于構(gòu)建API,它基于Python 3.6+的類型提示特性,使得代碼更加簡潔且易于綬護(hù),這篇文章主要介紹了Python FastAPI入門安裝使用,需要的朋友可以參考下
    2025-03-03
  • Python里隱藏的“禪”

    Python里隱藏的“禪”

    這篇文章主要介紹了IT柏拉圖翻譯的python的lib目錄下this.py文件中的一首詩,蘊含了Python程序設(shè)計中很多哲理性的規(guī)律,需要的朋友可以參考下
    2014-06-06
  • Python中__del__方法的使用方法詳細(xì)解析

    Python中__del__方法的使用方法詳細(xì)解析

    __del__()稱為“析構(gòu)方法”,用于實現(xiàn)對象被銷毀時所需的操作,下面這篇文章主要給大家介紹了關(guān)于Python中__del__方法的使用方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Python從list類型、range()序列簡單認(rèn)識類(class)【可迭代】

    Python從list類型、range()序列簡單認(rèn)識類(class)【可迭代】

    這篇文章主要介紹了Python從list類型、range()序列簡單認(rèn)識類(class),結(jié)合實例形式分析了list、range及自定義類等可迭代數(shù)據(jù)類型相關(guān)使用技巧,需要的朋友可以參考下
    2019-05-05
  • 使用Python操作FTP實現(xiàn)上傳和下載的方法

    使用Python操作FTP實現(xiàn)上傳和下載的方法

    今天小編就為大家分享一篇關(guān)于使用Python操作FTP實現(xiàn)上傳和下載的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • ubuntu 18.04搭建python環(huán)境(pycharm+anaconda)

    ubuntu 18.04搭建python環(huán)境(pycharm+anaconda)

    這篇文章主要為大家詳細(xì)介紹了ubuntu 18.04搭建python環(huán)境,包括Anaconda安裝、Pycharm安裝及初始配置,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • python離散建模之感知器學(xué)習(xí)算法

    python離散建模之感知器學(xué)習(xí)算法

    這篇文章主要介紹了python離散建模之感知器學(xué)習(xí)算法,感知機學(xué)習(xí)算法是支持向量機的基礎(chǔ),支持向量機通過核函數(shù)進(jìn)行非線性分類,支持向量機也是感知機算法的延伸,下面就來介紹感知算法的相關(guān)內(nèi)容,需要的小伙伴可以參考一下
    2022-02-02
  • python八皇后問題的解決方法

    python八皇后問題的解決方法

    這篇文章主要為大家詳細(xì)介紹了python八皇后問題的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09

最新評論