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

淺析如何在Python中使用結(jié)構(gòu)模式匹配

 更新時(shí)間:2023年08月11日 14:25:28   作者:Serdar Yegulalp  
在Python 3.10中引入了模式匹配語(yǔ)法,允許我們?cè)趹?yīng)用程序中使用強(qiáng)大的新編程技術(shù)進(jìn)行決策,下面我們就來(lái)講講如何在Python中使用結(jié)構(gòu)模式匹配吧

在Python 3.10中引入的模式匹配語(yǔ)法允許在應(yīng)用程序中使用強(qiáng)大的新編程技術(shù)進(jìn)行決策。Python雖然功能強(qiáng)大且廣受歡迎,但長(zhǎng)期以來(lái)缺乏其他語(yǔ)言中的一種流程控制方式,即以一種優(yōu)雅的方式將一個(gè)值與多個(gè)可能的條件進(jìn)行匹配。在C和C++中,這是通過(guò)構(gòu)造switch/case語(yǔ)句來(lái)實(shí)現(xiàn)的;在Rust中,這被稱為“模式匹配”。

在Python中,傳統(tǒng)的實(shí)現(xiàn)方式并不優(yōu)雅。一種方式是編寫(xiě)一系列的表達(dá)式。另一種方式是將要匹配的值作為字典的鍵存儲(chǔ)起來(lái),然后使用這些值來(lái)執(zhí)行相應(yīng)的操作,例如將函數(shù)作為值存儲(chǔ),并使用鍵或其他變量作為輸入。在許多情況下,這種方式可以很好地工作,但構(gòu)建和維護(hù)起來(lái)可能會(huì)很麻煩,使用if/elif/else語(yǔ)句。

在經(jīng)過(guò)多次失敗的提案后,Python語(yǔ)言創(chuàng)始人Guido van Rossum和其他一些貢獻(xiàn)者最近提出的一個(gè)提案已被接受,將在Python 3.10中引入結(jié)構(gòu)化模式匹配。結(jié)構(gòu)化模式匹配不僅可以執(zhí)行簡(jiǎn)單的樣式匹配,還支持更廣泛的用例。

Python結(jié)構(gòu)化模式匹配

結(jié)構(gòu)化模式匹配引入了語(yǔ)句和模式語(yǔ)法到Python中。該語(yǔ)句遵循與if/elif/else相同的基本概述。它接受一個(gè)對(duì)象,對(duì)該對(duì)象進(jìn)行一項(xiàng)或多項(xiàng)匹配模式的測(cè)試,并在找到匹配時(shí)執(zhí)行相應(yīng)的操作。

match command:
    case "quit":
        quit()
    case "reset":
        reset()
    case unknown_command:
        print (f"Unknown command '{unknown_command}'")

每個(gè)語(yǔ)句后面都跟著一個(gè)要匹配的模式。 在上面的示例中,我們使用簡(jiǎn)單的字符串作為我們的匹配目標(biāo),但更復(fù)雜的匹配也是可能的。事實(shí)上,結(jié)構(gòu)化模式匹配的主要用例是匹配類型的模式,而不是值的模式。Python通過(guò)從上到下遍歷案例列表來(lái)執(zhí)行匹配。在第一個(gè)匹配時(shí),Python執(zhí)行相應(yīng)塊中的語(yǔ)句,然后跳到塊的末尾并繼續(xù)執(zhí)行程序的其余部分。在案例之間沒(méi)有“穿透”,但可以設(shè)計(jì)邏輯來(lái)處理單個(gè)塊中的多個(gè)可能情況。(稍后會(huì)詳細(xì)介紹)還可以捕獲匹配的全部或部分內(nèi)容并重新使用它。在上面的示例中,如果沒(méi)有匹配成功,值將被“捕獲”在變量中,以便我們可以重新使用它。

用Python結(jié)構(gòu)模式匹配對(duì)變量進(jìn)行匹配

這里有一個(gè)需要注意的事項(xiàng)。如果在語(yǔ)句中列出變量名,這并不意味著應(yīng)該對(duì)命名變量的內(nèi)容進(jìn)行匹配。在case語(yǔ)句中,變量用于捕獲正在匹配的值。如果想要匹配變量的內(nèi)容,那么該變量必須以點(diǎn)分隔的名稱表示,就像枚舉一樣。以下是一個(gè)示例:

from enum import Enum
class Command(Enum):
    QUIT = 0
    RESET = 1
?
match command:
    case Command.QUIT:
        quit()
    case Command.RESET:
        reset()

不必使用枚舉;任何點(diǎn)分隔的屬性名稱都可以。但是枚舉通常是在Python中執(zhí)行此操作的最熟悉和慣用的方式。不能通過(guò)索引來(lái)匹配變量的內(nèi)容。例如,x[0]將被拒絕作為語(yǔ)法錯(cuò)誤。

使用Python結(jié)構(gòu)化模式匹配進(jìn)行多個(gè)元素的匹配

與模式匹配最有效的工作的關(guān)鍵不僅僅是將其用作字典查找或if/else鏈的替代品。它是描述要匹配的結(jié)構(gòu)的方式。通過(guò)這種方式,可以根據(jù)要匹配的元素?cái)?shù)量或它們的組合進(jìn)行匹配。這里是一個(gè)稍微復(fù)雜一些的例子。在這個(gè)例子中,用戶輸入一個(gè)命令,可選擇性地跟著一個(gè)文件名。

command = input("Command:")
match command.split():
    case ["quit"]:
        quit()
    case ["load", filename]:
        load_from(filename)
    case ["save", filename]:
        save_to(filename)
    case _:
        print (f"Command '{command}' not understood")

我們依次來(lái)看一下這些情況:

  • case ["quit"]:測(cè)試我們正在匹配的是否是只包含一個(gè)元素的列表,該元素是由輸入進(jìn)行拆分得到的字符串"quit"。
  • case ["load", filename]:測(cè)試第一個(gè)拆分元素是否是字符串"load",并且是否有一個(gè)緊隨其后的字符串。如果是這樣,我們將第二個(gè)字符串存儲(chǔ)在變量filename中,并將其用于進(jìn)一步的操作。
  • case ["save", filename]:與上述情況類似,測(cè)試第一個(gè)拆分元素是否是字符串"save",并且是否有一個(gè)緊隨其后的字符串。如果是這樣,我們將第二個(gè)字符串存儲(chǔ)在變量filename中,并將其用于進(jìn)一步的操作。
  • case _:這是一個(gè)通配符匹配。如果到目前為止沒(méi)有進(jìn)行其他匹配,它將匹配。請(qǐng)注意,下劃線變量_實(shí)際上不綁定到任何內(nèi)容;該名稱用作命令的信號(hào),表示該情況是一個(gè)通配符。(這就是為什么我們?cè)趬K的主體中引用該變量;沒(méi)有捕獲到任何內(nèi)容。)

在Python中結(jié)構(gòu)模式的匹配模式

模式可以是簡(jiǎn)單的值,也可以包含更復(fù)雜的匹配邏輯。以下是一些示例:

case "a":匹配單個(gè)值"a"。 

case ["a","b"]:匹配集合["a","b"]。 

case ["a", value1]:匹配包含兩個(gè)值的集合,并將第二個(gè)值放入捕獲變量value1中。 

case ["a", *values]:匹配至少包含一個(gè)值的集合。其他值(如果有)將存儲(chǔ)在values中。請(qǐng)注意,每個(gè)集合中只能包含一個(gè)星號(hào)項(xiàng)(就像在Python函數(shù)中的星號(hào)參數(shù)一樣)。 

case ("a"|"b"|"c"):使用括號(hào)運(yùn)算符()可以在單個(gè)塊中處理多個(gè)情況。在這里,我們匹配"a"、"b""c"。 

case ("a"|"b"|"c") as letter:與上述情況類似,只是現(xiàn)在將匹配的項(xiàng)放入變量letter中。 

case ["a", value] if :僅當(dāng)表達(dá)式為真時(shí)才匹配捕獲??梢栽诒磉_(dá)式中使用捕獲變量。例如,如果我們使用value in valid_values,則只有在捕獲的值實(shí)際上在集合valid_values中時(shí),才會(huì)匹配。 

case ["z", _]:以"z"開(kāi)頭的任何項(xiàng)集合都會(huì)匹配。

使用Python結(jié)構(gòu)化模式匹配對(duì)對(duì)象進(jìn)行匹配

Python結(jié)構(gòu)化模式匹配系統(tǒng)最高級(jí)的功能是能夠針對(duì)具有特定屬性的對(duì)象進(jìn)行匹配??紤]一個(gè)應(yīng)用程序,我們正在處理一個(gè)名為data的對(duì)象,我們希望將其轉(zhuǎn)換為文件并從函數(shù)中返回。

match media_object:
    case Image(codec="jpg"):
        # Return as-is
        return media_object
    case Image(codec="png") | Image(codec="gif"):
        return render_as(media_object, "jpg")
    case Video():
        raise ValueError("Can't extract frames from video yet")
    case other_type:
        raise Exception(f"Media object {media_object} 
            of type {codec} can't be handled yet")

在上述每種情況中,我們都在尋找特定類型的對(duì)象,有時(shí)還具有特定的屬性。第一個(gè)情況匹配具有屬性image_codec設(shè)置為"jpg"的對(duì)象。第二個(gè)情況匹配如果type"png""gif"。第三個(gè)情況匹配任何類型為Video的對(duì)象,無(wú)論其屬性如何。最后一個(gè)情況是我們的通配情況,如果其他情況都不匹配,它將捕獲所有對(duì)象,盡管我們使用了一個(gè)實(shí)際的名稱來(lái)捕獲它,而不是使用_。我們還可以在對(duì)象匹配中進(jìn)行捕獲:

match media_object:
    case Image(codec=media_type):
        print (f"Image of type {media_type}")

有效地使用Python結(jié)構(gòu)模式匹配

Python結(jié)構(gòu)化模式匹配的關(guān)鍵是編寫(xiě)能夠覆蓋所要匹配的結(jié)構(gòu)情況的匹配。對(duì)常量進(jìn)行簡(jiǎn)單的測(cè)試是可以的,但如果只是這樣做,那么簡(jiǎn)單的字典查找可能是一個(gè)更好的選擇。結(jié)構(gòu)化模式匹配的真正價(jià)值在于能夠根據(jù)對(duì)象的模式進(jìn)行匹配,而不僅僅是一個(gè)特定的對(duì)象或一組對(duì)象的選擇。另一個(gè)重要的事情是要記住匹配的順序。你首先測(cè)試哪些匹配將對(duì)整體匹配的效率和準(zhǔn)確性產(chǎn)生影響。大多數(shù)構(gòu)建了長(zhǎng)鏈的人會(huì)意識(shí)到這一點(diǎn),但由于潛在的復(fù)雜性,模式匹配要求你更加仔細(xì)地思考順序。將最具體的匹配放在最前面,將最一般的匹配放在最后。最后,如果你的問(wèn)題可以用簡(jiǎn)單的鏈?zhǔn)浇Y(jié)構(gòu)或字典查找來(lái)解決,那么請(qǐng)使用它!模式匹配是強(qiáng)大的,但并不是萬(wàn)能的。在解決問(wèn)題時(shí),請(qǐng)根據(jù)問(wèn)題的特點(diǎn)選擇最合適的方法。

到此這篇關(guān)于淺析如何在Python中使用結(jié)構(gòu)模式匹配的文章就介紹到這了,更多相關(guān)Python結(jié)構(gòu)模式匹配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python利用ElementTree模塊處理XML的方法詳解

    Python利用ElementTree模塊處理XML的方法詳解

    ElementTree是python的XML處理模塊,它提供了一個(gè)輕量級(jí)的對(duì)象模,下面這篇文章就來(lái)給大家介紹了關(guān)于Python利用ElementTree模塊處理XML的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-08-08
  • Python使用Yagmail庫(kù)實(shí)現(xiàn)自動(dòng)化郵件營(yíng)銷

    Python使用Yagmail庫(kù)實(shí)現(xiàn)自動(dòng)化郵件營(yíng)銷

    在數(shù)字營(yíng)銷領(lǐng)域,自動(dòng)化郵件營(yíng)銷是一種高效、低成本的方式,能夠幫助企業(yè)與客戶保持溝通,提升品牌忠誠(chéng)度,而Yagmail是一個(gè)簡(jiǎn)潔且功能強(qiáng)大的Python庫(kù),可以大大簡(jiǎn)化郵件發(fā)送的過(guò)程,本文將詳細(xì)介紹如何使用Yagmail庫(kù)來(lái)實(shí)現(xiàn)自動(dòng)化郵件營(yíng)銷,需要的朋友可以參考下
    2024-12-12
  • Win10+GPU版Pytorch1.1安裝的安裝步驟

    Win10+GPU版Pytorch1.1安裝的安裝步驟

    這篇文章主要介紹了Win10+GPU版Pytorch1.1安裝的安裝步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Pandas通過(guò)index選擇并獲取行和列

    Pandas通過(guò)index選擇并獲取行和列

    本文主要介紹了Pandas通過(guò)index選擇并獲取行和列,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Python Numpy學(xué)習(xí)之索引及切片的使用方法

    Python Numpy學(xué)習(xí)之索引及切片的使用方法

    數(shù)組中的元素可以通過(guò)索引以及切片的手段進(jìn)行訪問(wèn)或者修改,和列表的切片操作一樣。本文將詳細(xì)為大家介紹一下Python中的科學(xué)計(jì)算庫(kù)-Numpy的索引及切片的使用方法
    2022-01-01
  • conda虛擬環(huán)境使用pip下載包到當(dāng)前環(huán)境的兩種方法

    conda虛擬環(huán)境使用pip下載包到當(dāng)前環(huán)境的兩種方法

    conda管理包很方便,但并不是所有包都有最新的conda版本,所以仍需要使用conda中的pip來(lái)安裝包,下面這篇文章主要給大家介紹了關(guān)于conda虛擬環(huán)境使用pip下載包到當(dāng)前環(huán)境的兩種方法,需要的朋友可以參考下
    2022-08-08
  • python繪制簡(jiǎn)單彩虹圖

    python繪制簡(jiǎn)單彩虹圖

    這篇文章主要為大家詳細(xì)介紹了python繪制簡(jiǎn)單彩虹圖的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • python中導(dǎo)入 train_test_split提示錯(cuò)誤的解決

    python中導(dǎo)入 train_test_split提示錯(cuò)誤的解決

    這篇文章主要介紹了python中導(dǎo)入 train_test_split提示錯(cuò)誤的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • python實(shí)現(xiàn)圖片變亮或者變暗的方法

    python實(shí)現(xiàn)圖片變亮或者變暗的方法

    這篇文章主要介紹了python實(shí)現(xiàn)圖片變亮或者變暗的方法,涉及Python中Image模塊操作圖片的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • Python如何根據(jù)頁(yè)碼處理PDF文件的內(nèi)容

    Python如何根據(jù)頁(yè)碼處理PDF文件的內(nèi)容

    在Python中,fitz庫(kù)可以用于多種任務(wù),如打開(kāi)PDF文件、遍歷頁(yè)面、添加注釋、提取文本、旋轉(zhuǎn)頁(yè)面等,此外,它還可以用于在PDF頁(yè)面上添加高亮注釋、提取圖像等操作,這篇文章主要介紹了Python根據(jù)頁(yè)碼處理PDF文件的內(nèi)容,需要的朋友可以參考下
    2024-06-06

最新評(píng)論