0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳解Python里的分支代碼

python爬蟲知識分享 ? 來源:python爬蟲知識分享 ? 作者:python爬蟲知識分享 ? 2022-04-21 15:20 ? 次閱讀

Python 里的分支代碼

Python 支持最為常見的 if/else 條件分支語句,不過它缺少在其他編程語言中常見的 switch/case 語句。

除此之外,Python 還為 for/while 循環(huán)以及 try/except 語句提供了 else 分支,在一些特殊的場景下,它們可以大顯身手。

1. 避免多層分支嵌套

如果這篇文章只能刪減成一句話就結(jié)束,那么那句話一定是“要竭盡所能的避免分支嵌套”。

過深的分支嵌套是很多編程新手最容易犯的錯誤之一。假如有一位新手 JavaScript 程序員寫了很多層分支嵌套,那么你可能會看到一層又一層的大括號:if { if { if { ... }}}。俗稱“嵌套 if 地獄(Nested If Statement Hell)”。

但是因?yàn)?Python 使用了縮進(jìn)來代替 {},所以過深的嵌套分支會產(chǎn)生比其他語言下更為嚴(yán)重的后果。比如過多的縮進(jìn)層次很容易就會讓代碼超過 PEP8 中規(guī)定的每行字?jǐn)?shù)限制。讓我們看看這段代碼:

def buy_fruit(nerd, store):
    """去水果店買蘋果

    - 先得看看店是不是在營業(yè)
    - 如果有蘋果的話,就買 1 個
    - 如果錢不夠,就回家取錢再來
    """
    if store.is_open():
        if store.has_stocks("apple"):
            if nerd.can_afford(store.price("apple", amount=1)):
                nerd.buy(store, "apple", amount=1)
                return
            else:
                nerd.go_home_and_get_money()
                return buy_fruit(nerd, store)
        else:
            raise MadAtNoFruit("no apple in store!")
    else:
        raise MadAtNoFruit("store is closed!")

上面這段代碼最大的問題,就是過于直接翻譯了原始的條件分支要求,導(dǎo)致短短十幾行代碼包含了有三層嵌套分支。

這樣的代碼可讀性和維護(hù)性都很差。不過我們可以用一個很簡單的技巧:“提前結(jié)束” 來優(yōu)化這段代碼:

def buy_fruit(nerd, store):
    if not store.is_open():
        raise MadAtNoFruit("store is closed!")

    if not store.has_stocks("apple"):
        raise MadAtNoFruit("no apple in store!")

    if nerd.can_afford(store.price("apple", amount=1)):
        nerd.buy(store, "apple", amount=1)
        return
    else:
        nerd.go_home_and_get_money()
        return buy_fruit(nerd, store)

“提前結(jié)束”指:在函數(shù)內(nèi)使用 returnraise 等語句提前在分支內(nèi)結(jié)束函數(shù)。比如,在新的 buy_fruit 函數(shù)里,當(dāng)分支條件不滿足時,我們直接拋出異常,結(jié)束這段這代碼分支。這樣的代碼沒有嵌套分支,更直接也更易讀。

2. 封裝那些過于復(fù)雜的邏輯判斷

如果條件分支里的表達(dá)式過于復(fù)雜,出現(xiàn)了太多的 not/and/or,那么這段代碼的可讀性就會大打折扣,比如下面這段代碼:

# 如果活動還在開放,并且活動剩余名額大于 10,為所有性別為女性,或者級別大于 3
# 的活躍用戶發(fā)放 10000 個金幣
if activity.is_active and activity.remaining > 10 and \
        user.is_active and (user.sex == 'female' or user.level > 3):
    user.add_coins(10000)
    return

對于這樣的代碼,我們可以考慮將具體的分支邏輯封裝成函數(shù)或者方法,來達(dá)到簡化代碼的目的:

if activity.allow_new_user() and user.match_activity_condition():
    user.add_coins(10000)
    return

事實(shí)上,將代碼改寫后,之前的注釋文字其實(shí)也可以去掉了。因?yàn)楹竺孢@段代碼已經(jīng)達(dá)到了自說明的目的。至于具體的 什么樣的用戶滿足活動條件? 這種問題,就應(yīng)由具體的 match_activity_condition() 方法來回答了。

Hint: 恰當(dāng)?shù)姆庋b不光直接改善了代碼的可讀性,事實(shí)上,如果上面的活動判斷邏輯在代碼中出現(xiàn)了不止一次的話,封裝更是必須的。不然重復(fù)代碼會極大的破壞這段邏輯的可維護(hù)性。

3. 留意不同分支下的重復(fù)代碼

重復(fù)代碼是代碼質(zhì)量的天敵,而條件分支語句又非常容易成為重復(fù)代碼的重災(zāi)區(qū)。所以,當(dāng)我們編寫條件分支語句時,需要特別留意,不要生產(chǎn)不必要的重復(fù)代碼。

讓我們看下這個例子:

# 對于新用戶,創(chuàng)建新的用戶資料,否則更新舊資料
if user.no_profile_exists:
    create_user_profile(
        username=user.username,
        email=user.email,
        age=user.age,
        address=user.address,
        # 對于新建用戶,將用戶的積分置為 0
        points=0,
        created=now(),
    )
else:
    update_user_profile(
        username=user.username,
        email=user.email,
        age=user.age,
        address=user.address,
        updated=now(),
    )

在上面的代碼中,我們可以一眼看出,在不同的分支下,程序調(diào)用了不同的函數(shù),做了不一樣的事情。但是,因?yàn)槟切┲貜?fù)代碼的存在,我們卻很難簡單的區(qū)分出,二者的不同點(diǎn)到底在哪。

其實(shí),得益于 Python 的動態(tài)特性,我們可以簡單的改寫一下上面的代碼,讓可讀性可以得到顯著的提升:

if user.no_profile_exists:
    profile_func = create_user_profile
    extra_args = {'points': 0, 'created': now()}
else:
    profile_func = update_user_profile
    extra_args = {'updated': now()}

profile_func(
    username=user.username,
    email=user.email,
    age=user.age,
    address=user.address,
    **extra_args
)

當(dāng)你編寫分支代碼時,請額外關(guān)注由分支產(chǎn)生的重復(fù)代碼塊,如果可以簡單的消滅它們,那就不要遲疑。

4. 謹(jǐn)慎使用三元表達(dá)式

三元表達(dá)式是 Python 2.5 版本后才支持的語法。在那之前,Python 社區(qū)一度認(rèn)為三元表達(dá)式?jīng)]有必要,我們需要使用 x and a or b 的方式來模擬它。[注]

事實(shí)是,在很多情況下,使用普通的 if/else 語句的代碼可讀性確實(shí)更好。盲目追求三元表達(dá)式很容易誘惑你寫出復(fù)雜、可讀性差的代碼。

所以,請記得只用三元表達(dá)式處理簡單的邏輯分支。

language = "python" if you.favor("dynamic") else "golang"

對于絕大多數(shù)情況,還是使用普通的 if/else 語句吧。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4697

    瀏覽量

    68085
  • python
    +關(guān)注

    關(guān)注

    54

    文章

    4758

    瀏覽量

    84293
收藏 人收藏

    評論

    相關(guān)推薦

    python中open函數(shù)的用法詳解

    python中open函數(shù)的用法詳解 Python中的open()函數(shù)用于打開文件。它接受文件名和模式作為參數(shù),并返回一個文件對象。文件對象可用于讀取、寫入和管理文件。 open()函數(shù)的基本語法
    的頭像 發(fā)表于 01-30 15:31 ?1731次閱讀

    Python智能家居系統(tǒng)代碼介紹

    Python智能家居系統(tǒng)是一種基于Python編程語言開發(fā)的智能家居控制系統(tǒng),在現(xiàn)代家庭中得到了越來越廣泛的應(yīng)用。本文將詳細(xì)介紹Python智能家居系統(tǒng)的代碼實(shí)現(xiàn),包括系統(tǒng)的結(jié)構(gòu)與功能
    的頭像 發(fā)表于 01-25 09:46 ?1162次閱讀

    Git命令之本地分支與遠(yuǎn)程分支關(guān)聯(lián)和解除

    在實(shí)際的工作生活中,往往需要將本地的分支和遠(yuǎn)程分支關(guān)聯(lián),這樣我們就可以使用git pull命令來更新拉取最新的代碼,并使用git push命令將自己本地的修改推送到遠(yuǎn)程倉庫。但是如果此時你本地關(guān)聯(lián)
    的頭像 發(fā)表于 12-15 09:27 ?2680次閱讀
    Git命令之本地<b class='flag-5'>分支</b>與遠(yuǎn)程<b class='flag-5'>分支</b>關(guān)聯(lián)和解除

    python軟件IDLE怎么打多行代碼

    用于編寫、編輯和運(yùn)行Python代碼的編輯器窗口。在IDLE中編寫多行代碼有幾種方法可以實(shí)現(xiàn)。 使用括號與換行符: 在IDLE中編寫多行代碼的一種常見方法是使用括號來將多行
    的頭像 發(fā)表于 11-29 15:00 ?3627次閱讀

    python shell怎么用

    Python Shell是一種交互式解釋器,可以通過命令行直接運(yùn)行Python代碼。在Shell中,可以輸入一行代碼并立即得到結(jié)果,非常適合于測試、嘗試新
    的頭像 發(fā)表于 11-29 14:36 ?1026次閱讀

    python軟件怎么運(yùn)行代碼

    Python是一種高級編程語言,它被廣泛用于開發(fā)各種類型的應(yīng)用程序,從簡單的腳本到復(fù)雜的網(wǎng)絡(luò)應(yīng)用和機(jī)器學(xué)習(xí)模型。要運(yùn)行Python代碼,您需要一個Python解釋器,它可以將您的
    的頭像 發(fā)表于 11-28 16:02 ?819次閱讀

    python如何換行而不運(yùn)行代碼

    Python程序中的換行是指在代碼中使用特定的語法來表示換行,以使代碼更易讀。換行的目的是為了讓程序更具可讀性并提高代碼的可維護(hù)性。然而,換行不會對程序的執(zhí)行產(chǎn)生任何影響,它只是改善了
    的頭像 發(fā)表于 11-24 09:50 ?2957次閱讀

    python代碼寫完后點(diǎn)哪個運(yùn)行

    當(dāng)你完成了編寫Python代碼后,你可以選擇多種方式來運(yùn)行它。下面是幾種常見的運(yùn)行代碼的方式: Python解釋器:Python是一種解釋型
    的頭像 發(fā)表于 11-24 09:28 ?4146次閱讀

    python如何一直循環(huán)一個代碼

    Python中,有幾種方法可以實(shí)現(xiàn)代碼的循環(huán)執(zhí)行。下面我將詳盡、詳實(shí)、細(xì)致地介紹這些方法和它們的使用情況。 使用while循環(huán): 在Python中,可以使用while循環(huán)來重復(fù)執(zhí)行一段代碼
    的頭像 發(fā)表于 11-23 15:54 ?2163次閱讀

    Python自帶的命令窗口

    Python自帶的命令窗口,也稱為Python交互式解釋器,是Python編程語言的一個重要工具,它允許用戶在命令行界面中輸入和執(zhí)行Python代碼
    的頭像 發(fā)表于 11-22 14:02 ?809次閱讀

    python如何換行而不運(yùn)行代碼

    Python中,換行是一種用來增加代碼的可讀性和組織性的方式。當(dāng)你在編寫Python代碼時,換行通常用于分隔不同的代碼行或塊,使其更易于閱
    的頭像 發(fā)表于 11-22 10:52 ?2308次閱讀

    python怎樣運(yùn)行代碼

    討論Python代碼的運(yùn)行方式,包括解釋器、交互式環(huán)境和命令行。 Python代碼可以通過兩種主要的方式運(yùn)行:解釋執(zhí)行和編譯執(zhí)行。解釋執(zhí)行是指將源
    的頭像 發(fā)表于 11-22 10:31 ?1086次閱讀

    python循環(huán)的輸出結(jié)果匯總

    循環(huán)是計(jì)算機(jī)編程中常用的一種控制結(jié)構(gòu),用于重復(fù)執(zhí)行一段代碼。Python提供了多種類型的循環(huán)結(jié)構(gòu),包括for循環(huán)和while循環(huán)。在這篇文章中,我們將詳細(xì)介紹Python循環(huán)中的輸出結(jié)果。 首先
    的頭像 發(fā)表于 11-22 09:59 ?1420次閱讀

    pythonitem的用法

    item是Python中一個非常重要的概念,它可以用于多種數(shù)據(jù)結(jié)構(gòu)和算法的實(shí)現(xiàn)。在Python中,item通常用于表示一個集合或序列中的一個元素。本文將詳細(xì)介紹item的用法,并探討它在列表、字典
    的頭像 發(fā)表于 11-21 15:09 ?3210次閱讀

    Python 如何一鍵轉(zhuǎn)化代碼為流程圖

    天我們要介紹的項(xiàng)目,就是基于Python和Graphviz開發(fā)的,能將源代碼轉(zhuǎn)化為流程圖的工具:pycallgraph。 1.準(zhǔn)備 開始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒有
    的頭像 發(fā)表于 11-01 10:39 ?2042次閱讀
    <b class='flag-5'>Python</b> 如何一鍵轉(zhuǎn)化<b class='flag-5'>代碼</b>為流程圖