目錄
1、switch 是什麼?
4、未来会有 switch 语句么?
首頁 後端開發 Python教學 Python 為什麼不支援 switch 語句?

Python 為什麼不支援 switch 語句?

Oct 10, 2020 pm 05:48 PM
python switch

Python教學欄位這篇文章裡,我們會聊一聊為什麼 Python 決定不支援 switch 語句。

Python 為什麼不支援 switch 語句?

為什麼想要聊這個主題呢?

主要是因為switch 在其它語言中太常見了,而Python 卻不支持,這樣的獨特性本身就值得關注,而回答這個問題,也能更加看清Python 在程式設計上的理念,了解Python 在語法設計中的決策過程。

本文除了會詳細分析PEP-275 和PEP-3103,還會介紹到Python 最新的發展動態(PEP-622),即可能要引入的模式匹配(pattern matching)語法,相信這個話題會開拓大家的眼界,對switch 文法有更全面的認識。

1、switch 是什麼?

在開始正題之前,我們需要先聊聊 switch 是什麼?

有些同學可能會第一時間想到它…

Python 為什麼不支援 switch 語句?

餵~餵~,麻煩收收心,別總想著遊戲啦,我們要說的是程式語言中的switch 語句。

一般而言,switch 的語法格式如下:

switch(expression){    case value1:       // 语句
       break; // 可选
    case value2:       // 语句
       break; // 可选
    default: // 可选
       // 语句}复制代码
登入後複製

使用流程圖來表示,大概是這樣的:

Python 為什麼不支援 switch 語句?

##它的用法不難理解:switch 語句的值滿足哪一個case 情況,就會執行對應的程式碼區塊,執行時遇到break 就跳出,否則就繼續執行下一個case 分支;一般會在最後放一個default 分支,作為兜底。

大多數語言都提供了switch 語句或極其相似的東西,例如,在C/C /Java /Go 等靜態語言中,它們都支援switch-case 結構;在Ruby 中有類似的case -when 結構,在Shell 語言中,有相似的case-in 結構,在Perl 中,有switch-case-else…

switch 語句的好處是支援「單一條件多分支」的選擇結構,相較於if-else 的二分選擇結構,在某些時候會更為簡潔清晰。

但是,在 Python 中,我們看不到 switch-case 或相似的語法結構,這是為什麼呢?

2、Python 為什麼不支援switch?

官方文件中有一篇FAQ 包含了這個問題:Why isn't there a switch or case statement in Python?

Python 為什麼不支援 switch 語句?

FAQ 即Frequently Asked Questions 的縮寫,表示常見問題,官方列了27 個常見問題,完整清單在此:mp.weixin.qq.com/s/zabIvt4df…

該文件給了幾個建議,告訴了我們幾個switch/case 的替代方案:

    使用if-elif-else 條件判斷語句
  • 使用字典,將case 值與呼叫的函數映射起來
  • 使用內建getattr() 檢索特定的物件呼叫方法
曾有人提出過一些提案(即PEP -275 和PEP-3103),想給Python 引入switch 語法,然而,對於“

是否以及如何進行靶場測試”,大家沒有達成一致的共識。

靶場測試,即 range test,指的是對武器彈藥的技術性能作各種測試驗證,與藥物的臨床試驗一樣,都是在最終產品交付前的一項關鍵性測試。

官方文件對於「為什麼Python 不引入switch」的解釋,實際上來自Python 之父Guido van Rossum 在PEP-3103 中的意見:

Python 為什麼不支援 switch 語句?

#來源:www.python.org/dev/peps/pe…

A quick poll during my keynote presentation at PyCon 2007 shows this proposal has no popular support. I therefore reject it.

#我在PyCon 2007 的主題演講中做了一個快速的民意調查,結果顯示這個提案沒有得到廣泛的支持。因此,我拒絕了它。

簡而言之,

PEP 提案有了,語法實作也有了雛形,但是核心開發者們似乎沒有達成一致意見,最終導致提案流產了。

3、PEP-275 與 PEP-3103 說了什麼?

PEP-3103 是在2006 年提出的,PEP-275 則是在2001 年提出的,它們的共同之處是提出了引入switch 語句的某種必要性、分析了好幾種備選的實現方案,然而,結局是都被拒絕了。

Python 為什麼不支援 switch 語句?

出處:www.python.org/dev/peps/pe…

那么,我们就先来回顾一下核心开发者们都做出了哪些讨论,看一看如果 Python 要实现 switch 结构,会是怎么样子的?(PS:PEP 里还涉及其它内容,本文只摘取与 switch 直接相关的部分)

PEP-275 提出的语法结构如下:

switch EXPR:
    case CONSTANT:
        SUITE
    case CONSTANT:
        SUITE
    ...    else:
        SUITE复制代码
登入後複製

其中 else 分支是可选的,如果没有它,并且前面的分支都不满足的话,就什么也不做。另外 case 值 constant 支持不同类型,因为 expr 表达式的类型是动态的。

PEP-275 还提出让 switch 不支持掉落(fall-through)行为,即每个 case 分支相互独立而完整,不用像 C 语言那样需要写 break。

该 PEP 还列举了一些其它的 issue:

  • 重用现有关键字,不引入“switch”和“case”
  • 使用新的关键字,避免与 C 的 switch 概念混淆
  • 支持单分支多值选择(例如:case 'a', 'b', 'c': ...)
  • 还有建议支持范围取值判断(例如:case 10..14: ...)

除了首选方案,该 PEP 还记录了几种风格各异的语法方案:

case EXPR:
    of CONSTANT:
        SUITE
    of CONSTANT:
        SUITE    else:
        SUITE

case EXPR:    if CONSTANT:
         SUITE    if CONSTANT:
        SUITE    else:
        SUITE

when EXPR:    in CONSTANT_TUPLE:
        SUITE    in CONSTANT_TUPLE:
        SUITE
    ...else:
     SUITE复制代码
登入後複製

PEP-275 记录下了不少重要的思路和问题,为 PEP-3103 的出现做了很好的铺垫。

那么,我们再来看看由 Guido 编写的 PEP-3103 说了些什么吧。

它首先认可了 PEP-275 中的两个基础设定,例如,实现“隐式的 break”,不让 case 分支出现 fall-through 这种转移控制权的情况(其它语言似乎都要求显式地写 break);else 分支是可选的,复用 else 关键字,而不用引入“default”。

对于 PEP-275 提倡的那种风格,Guido 比较认可,但也认为它的问题是缩进层次太多,因此建议减少代码分支缩进的空格数,例如本来缩进 4 空格,改为缩进 2 空格。

PEP-3103 还列举了另外三种实现方案,分析了它们的差异以及问题,具体内容从略,这里只给大家看看它们的风格:

# case 分支不缩进switch EXPR:
case EXPR:
    SUITE
case EXPR:
    SUITE
....else:
    SUITE# switch 语句后不加冒号switch EXPR
case EXPR:
    SUITE
case EXPR:
    SUITE
....else:
    SUITE# 省略 case 关键字switch EXPR:
    EXPR:
        SUITE
    EXPR:
        SUITE
    ...    else:
        SUITE复制代码
登入後複製

在基础语法之外,Guido 花了很多篇幅来讨论扩展语法(Extended Syntax),即在一个 case 分支中实现匹配多个值的复杂情况:

case EXPR, EXPR, ...:# Guido 优选的case in EXPR_LIST:

case *EXPR:

case [*]EXPR, [*]EXPR, ...:

case *(EXPR, EXPR, ...):复制代码
登入後複製

他重点考虑到的问题包括:switch 中表达式的结果是元组或可迭代对象的情况、case 的值被看成元组解包的情况、在 case 分支作“*”星号操作……

接着,Guido 又用了非常非常多的篇幅来分析该如何实现 switch,其中讨论到的主要思路有:

  • 使用等价的 if-elif 链来定义 switch 语句(可能会做些优化)
  • 同上,另外所有表达式都必须是可哈希的(hashable)
  • 看作是预先计算的字典的分派(dispatch)

PEP 中这部分的内容非常多,因为在每个思路上,Guido 还考虑到了好几种实现路径,这导致了他在复杂分析后的结论是:It is too early to decide( 现在做决定为时尚早)。

阅读完 PEP-3103 后,我总体的感觉是:Guido 的思路非常发散、层次丰富,但是,缺少了他在面对其它问题时那“快刀斩乱麻”式的洞察力。

也就是说,在诸多的可能性方案中,他力求面面俱到,最终无法说服自己做出一个独裁的决定。阻力主要来自于他自己,而不是其他人。

不过,之所以会出现这种情况,也许跟他的预设立场有关:他似乎认为“Python is fine without a switch statement”,因此尽管写了很长的 PEP,但只是在把问题复杂化,把议题搁置起来。

最后,他在 PyCon 上做了一个小范围调查,借此“名正言顺”地拒绝了自己发起的 PEP,试图堵住众人的悠悠之口……

4、未来会有 switch 语句么?

归结起来,之所以 Python 没有 switch 语句,原因有:switch 的实现细节/功能点未经敲定、没有 switch 也挺好的、有其它不错的方法替代 switch、Guido 的小任性……

但是,我们还是要追问一句:未来会有 switch 语句么?或者类似的多分支选择结构?

为什么要有此一问呢?原因是有太多语言自带 switch 语句,而且也有很多人尝试编写提供 switch 功能的库(我记得在 PyCoder's Weekly 里曾见到过两次)。

我(Python猫)本人自始至终并不喜欢 switch,几乎可以肯定地说,Python 未来也不会有 switch,但是,它很可能会引入一个类似于 switch 且更为复杂的语法结构!

2020 年 6 月,PEP-622 被提出了,它建议引入在 Scala、Erlang 和 Rust 等语言中的模式匹配语法(pattern matching)。

Python 為什麼不支援 switch 語句?

截至 2020 年 10 月,该 PEP 已被分解成另外三个 PEP(634-636),目前都处于草案阶段。考虑到核心开发者们的参与情况以及话题讨论的情况,这些提案极有可能会在未来版本(比如正在开发中的 3.10)中实现。

以一个求平均数的函数为例,模式匹配语法可以实现成这样:

def average(*args):
    match args:
        case [x, y]:           # captures the two elements of a sequence
            return (x + y) / 2
        case [x]:              # captures the only element of a sequence
            return x
        case []:            return 0
        case x:                # captures the entire sequence
            return sum(x) / len(x)复制代码
登入後複製

match-case 结构神似于 switch-case 结构,然而它基于模式(pattern)而非表达式(expression),因此有更多待考虑的细节问题,也有更为广阔的应用空间。

对此话题感兴趣的读者,建议去查阅这几个新的 PEP。

最后,让我们回到标题中的问题:Python 为什么不支持 switch 语句?

官方文档的 FAQ 对此问题有一个解答,告诉我们有几个不错的替代写法,同时也留下了一条线索:曾有 PEP 提议引入 switch,只是没有成功实现。

沿着这条线索,本文拆解了 PEP-275 和 PEP-3103 这两篇文档,带大家看到了 Python 社区里提出过的风格各异的 switch 方案,以及诸多的悬而未决的问题。

最后,我们还关注到了最新的 PEP-622 的动态,看起来 switch 的“孪生兄弟” match 语法有望引入到 Python 中!switch 话题的讨论似乎要终止了,但是另一个更大的话题正在进行中!

相关免费学习推荐:python教程(视频)

以上是Python 為什麼不支援 switch 語句?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

vs code 可以在 Windows 8 中運行嗎 vs code 可以在 Windows 8 中運行嗎 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上運行,但體驗可能不佳。首先確保系統已更新到最新補丁,然後下載與系統架構匹配的VS Code安裝包,按照提示安裝。安裝後,注意某些擴展程序可能與Windows 8不兼容,需要尋找替代擴展或在虛擬機中使用更新的Windows系統。安裝必要的擴展,檢查是否正常工作。儘管VS Code在Windows 8上可行,但建議升級到更新的Windows系統以獲得更好的開發體驗和安全保障。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

vscode 擴展是否是惡意的 vscode 擴展是否是惡意的 Apr 15, 2025 pm 07:57 PM

VS Code 擴展存在惡意風險,例如隱藏惡意代碼、利用漏洞、偽裝成合法擴展。識別惡意擴展的方法包括:檢查發布者、閱讀評論、檢查代碼、謹慎安裝。安全措施還包括:安全意識、良好習慣、定期更新和殺毒軟件。

See all articles