当前位置: 首页 > 后端技术 > Python

为什么python不支持switch语句?

时间:2023-03-26 15:51:50 Python

作者:猫下豌豆花来源:Python猫这篇文章我们就来聊一聊为什么Python决定不支持switch语句。为什么要聊这个话题?主要是switch在其他语言中太常见了,python却不支持。这样的独特性值得关注。回答这个问题也能清楚的看出python在编程中的概念,理解python的语法设计。在决策过程中。本文除了详细分析PEP-275和PEP-3103之外,还将介绍Python(PEP-622)的最新进展,即可能引入的模式匹配语法。我相信这个话题会开阔你的视野。从而对switch语法有一个更全面的了解。1、什么是开关?在开始正题之前,我们需要先说一下什么是switch?有的同学可能是第一次想到……嘿嘿~,请放轻松,别老想着游戏,我们要说的是编程语言中的switch语句。一般来说,switch的语法格式如下:switch(expression){casevalue1://statementbreak;//可选的casevalue2://statementbreak;//optionaldefault://optional//statement}use用流程图来表示,大致是这样的:它的用法不难理解:switch语句的值满足哪种情况,对应的代码块就会被执行,执行中遇到break会跳出,否则继续执行下一个caseBranch;通常将默认分支放在末尾作为底线。大多数语言都提供了switch语句或者非常类似的东西,比如在C/C++/Java/Go等静态语言中,都支持switch-case结构;在Ruby中有类似的case-when结构,在Shell语言中,有类似的case-in结构。在Perl中,有switch-case-else...switch语句的优点是支持“单条件多分支”的选择结构。相比if-else的二元选择结构,in有时会更加简洁明了。然而,在Python中,我们并没有看到switch-case或类似的语法结构,这是为什么呢?2、为什么Python不支持switch?官方文档中有一个FAQ包含这个问题:为什么Python中没有switch或case语句?FAQ是FrequentlyAskedQuestions的缩写,意思是常见问题。官方27个常见问题列表完整问题列表在这里:https://mp.weixin.qq.com/s/za...这个文档给出了几个建议,告诉我们switch/case的几个替代方案:使用if-elif-else条件判断语句使用字典将case值映射到被调用函数使用内置的getattr()检索特定对象的调用方法有人提出了一些建议(即PEP-275和PEP-3103)引入switchtoPythonGrammar,然而,对于是否以及如何进行范围测试并没有一致的共识。射程试验,即射程试验,是指对武器弹药技术性能进行的各种试验和验证。就像药物的临床试验一样,它是最终产品交付前的关键测试。官方文档对“为什么Python不引入switch”的解释其实来自于Python之父GuidovanRossum在PEP-3103中的观点:来源:https://www.python.org/dev/pe。..我在PyCon2007的主题演讲中进行的一项快速调查显示,该提议没有得到普遍支持。因此我拒绝它。因此,我拒绝了。简而言之,有一个PEP提案和一个基本的语法实现,但核心开发人员似乎未能达成共识,最终导致该提案流产。3.PEP-275和PEP-3103说了什么?PEP-3103是2006年提出的,PEP-275是2001年提出的,它们的共同点是提出了引入switch语句的必要性,分析了几种备选的实现方式。然而,最终还是被拒绝了。来源:https://www.python.org/dev/pe...那么,我们先回顾一下核心开发者都做了哪些讨论,看看如果Python实现switch结构会是什么样子?(PS:PEP还涉及其他内容,本文只摘录与switch直接相关的部分)PEP-275提出的语法结构如下:switchEXPR:caseCONSTANT:SUITEcaseCONSTANT:SUITE...else:SUITEwheretheelse分支是可选的,没有它,并且前面的分支都不满足,什么都不做。此外,case值常量支持不同的类型,因为expr表达式的类型是动态的。PEP-275还提出switch不支持fall-through行为,即每个case分支都是独立完整的,不需要像C语言那样写break。PEP还列出了一些其他问题:重用现有关键字,不要为“switch”和“case”引入??新的关键字,避免与C的switch概念混淆支持单分支多值选择(例如:case'a','b','c':...)还有支持范围值判断的建议(例如:case10..14:...)除了首选方案外,本PEP还记录了几种不同风格的语法方案:caseEXPR:ofCONSTANT:SUITEofCONSTANT:SUITEelse:SUITEcaseEXPR:ifCONSTANT:SUITEifCONSTANT:SUITEelse:SUITEwhenEXPR:inCONSTANT_TUPLE:SUITEinCONSTANT_TUPLE:SUITE...else:SUITEPEP-275记录了很多重要的思想和问题,它为PEP-3103的出现铺平了道路。那么,让我们来看看Guido编写的PEP-3103是怎么说的。它首先识别PEP-275中的两个基本设置,比如实现“隐式break”,防止case分支中fall-through等控制权的转移(其他语言好像需要显式写break);else分支是可选的,在不引入“default”的情况下重用else关键字。Guido认同PEP-275所提倡的风格,但他也认为它的问题在于缩进层级过多。因此,建议减少代码分支缩进的空格数。比如原来的缩进是4个空格,缩进是2个空格。PEP-3103还列出了其他三种实现方案,并分析了它们的区别和问题。具体内容从略。这里只展示它们的样式:casebranchisnotindentedswitchEXPR:caseEXPR:SUITEcaseEXPR:SUITEelse:SUITEswitchwithoutacolonafterthestatementswitchEXPR:SUITEcaseEXPR:SUITEelse:SUITE省略case关键字switchEXPR:EXPR:SUITEEXPR:SUITE...else:SUITEGuido除了基本语法外,还花了大量篇幅讨论扩展语法(ExtendedSyntax),即实现一个case分支匹配多个值的复杂情况:caseEXPR,EXPR,...:Guido在EXPR_LIST中的首选情况:case*EXPR:case[]EXPR,[]EXPR,...:case*(EXPR,EXPR,...):他考虑的重点问题包括:switch中表达式的结果是元组或可迭代对象,case的值被视为解包后的元组situation,case分支中的“*”星号操作……然后,Guido花了很大篇幅来分析如何实现switch。里面讨论的主要思想是:使用等价的if-elif链来定义switch语句(可能有一些优化)同上,加上所有的表达式必须是hashable(dispatch)作为一个预计算字典在思路上,Guido也考虑了几种实现路径,经过复杂分析得出他的结论:Itistooearlytodecision(itistooearlytomakeadecisionnow)。看完PEP-3103,我的总体感觉是Guido的思维发散性很强,层次丰富,但缺乏面对其他问题时的“尖刀”洞察力。也就是说,在众多可能的解决方案中,他想尽办法涵盖了方方面面,但最终还是无法说服自己做出独裁的决定。阻力主要来自于自己,而不是来自他人。不过,造成这种情况的原因可能与他预设的立场有关:他似乎认为“Python没有switch语句也可以”,所以虽然他写了很长的PEP,但他只是把问题复杂化,把话题搁置了.最后他对PyCon进行了小范围的调查,以至于他“名正言顺”地拒绝了他发起的PEP,试图堵住大家的嘴……4.以后会有switch语句吗?总结一下,Python没有switch语句的原因有以下几点:switch的实现细节/功能点还没有敲定,没有switch也好,switch还有其他好的替代方法,Guido的小任性。..但是,我们还要追问一个问题:以后会不会有switch语句?或者类似的多分支选择结构?你为什么要问这个问题?原因是有switch语句的语言太多了,也有很多人尝试写提供switch功能的库(我记得在PyCoder的周刊上看过两次)。我(Python猫)从头到尾都不喜欢switch,几乎可以肯定以后python不会有switch,但是很有可能会引入更复杂的类似switch的语法结构!2020年6月,PEP-622提出,提出在Scala、Erlang、Rust等语言中引入模式匹配。截至2020年10月,该PEP已分解为另外三个PEP(634-636),目前均处于草案阶段。考虑到核心开发者的参与和话题的讨论,这些提议很有可能会在未来的版本中实现(比如正在开发的3.10)。以average函数为例,模式匹配语法可以这样实现:defaverage(*args):matchargs:case[x,y]:#捕获一个序列的两个元素return(x+y)/2case[x]:#捕获序列的唯一元素returnxcase[]:return0casex:#捕获整个序列returnsum(x)/len(x)match-case结构类似于switch-case结构,但它是基于模式(pattern)而非表达式(expression),因此需要考虑的细节更多,应用空间更广。建议对此主题感兴趣的读者查看这些新的PEP。最后,我们回到标题中的问题:为什么Python不支持switch语句?官方文档的FAQ对这个问题有回答,告诉我们有几个不错的替代方案,还留下了一个线索:曾经有PEP提议引入switch,但是没有成功实现。顺着这个线索,本文对PEP-275和PEP-3103这两个文档进行了拆解,向大家展示了Python社区中提出的不同风格的switch解决方案,以及很多未解决的问题。最后,我们还关注了PEP-622的最新进展。看来switch这个“孪生兄弟”匹配语法有望引入Python!关于switch主题的讨论似乎已经结束,但另一个更大的主题正在路上!