この記事の Python チュートリアル 列では、Python が switch ステートメントをサポートしないことを決定した理由について説明します。
なぜこのトピックについて話したいのですか?
主な理由は、switch は他の言語ではあまりにも一般的ですが、Python ではサポートされていないためです。この独自性自体は注目に値し、この質問に答えることで、Python のプログラミング哲学をより明確に理解することもできます。Python の意思決定を理解する構文設計のプロセス。
この記事では、PEP-275 と PEP-3103 を詳細に分析することに加えて、Python (PEP-622) の最新の開発動向、つまり導入される可能性のあるパターン マッチング構文についても紹介します。このトピックを信じてください。これにより、みんなの視野が広がり、switch 構文をより包括的に理解できるようになります。
始める前に、スイッチとは何かについて話す必要があります。
すぐに思いつく生徒もいるかもしれません...
おいおい、落ち着いてください、ゲームのことばかり考えてはいけません。私が話しているのは、プログラミング言語の switch ステートメントです。
一般的に、switch の構文形式は次のとおりです。
switch(expression){ case value1: // 语句 break; // 可选 case value2: // 语句 break; // 可选 default: // 可选 // 语句}复制代码
フローチャートを使用して表すと、次のようになります。
It カバーとしての使用法。
ほとんどの言語は、switch ステートメントまたはそれに非常に類似したものを提供します。たとえば、C/C/Java/Go などの静的言語では、すべて switch-case 構造がサポートされています。Ruby にも同様の構造があります。 case -when 構造。シェル言語には同様の case-in 構造があり、Perl には switch-case-else があります...
switch ステートメントの利点は、「」をサポートしていることです。単一の条件と複数の分岐の選択構造は、if-else のバイナリ選択構造と比較して、場合によってはより簡潔で明確になります。
しかし、Python では switch-case や同様の文法構造が見られません。これはなぜでしょうか?
公式ドキュメントには、この質問をカバーする FAQ があります: Why isn't there a switch or case state in Python?
FAQ は、Frequently Asked question の略で、よくある質問を意味します。よくある質問 27 件の公式リストは、mp.weixin.qq.com/ にあります。 s/zabIvt4df…
このドキュメントではいくつかの提案があり、switch/case の代替案がいくつか示されています。
いくつかの提案が行われています (つまり、 .PEP -275 および PEP-3103) は、Python に switch 構文を導入したいと考えていますが、「範囲テストを実行するかどうか、またその方法については 」について全会一致の合意はありません。
レンジテストはレンジテストとも呼ばれ、武器や弾薬の技術的性能を検証するためのさまざまなテストを指し、医薬品の臨床試験と同様、最終製品の納品前の重要なテストです。
公式ドキュメントの「Python がスイッチを導入しない理由」の説明は、実際には、PEP-3103 での Python の父である Guido van Rossum の意見から来ています。
#出典: www.python.org/dev/peps/pe…PyCon 2007 での私の基調講演中に簡単にアンケートをとったところ、この提案には一般的な支持がないことがわかりました。 PyCon 2007 の基調講演中に簡単なアンケートを実施しましたが、その結果、この提案は広く支持されていないことがわかりました。したがって、お断りさせていただきました。つまり、PEP 提案が提案され、構文の実装が具体化されましたが、コア開発者の間で合意に達していないようで、最終的には計画の中止につながりました。提案。
3. PEP-275 と PEP-3103 は何と言っていますか? PEP-3103 は 2006 年に提案され、PEP-275 は 2001 年に提案されましたが、共通しているのは、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:
除了首选方案,该 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,其中讨论到的主要思路有:
PEP 中这部分的内容非常多,因为在每个思路上,Guido 还考虑到了好几种实现路径,这导致了他在复杂分析后的结论是:It is too early to decide( 现在做决定为时尚早)。
阅读完 PEP-3103 后,我总体的感觉是:Guido 的思路非常发散、层次丰富,但是,缺少了他在面对其它问题时那“快刀斩乱麻”式的洞察力。
也就是说,在诸多的可能性方案中,他力求面面俱到,最终无法说服自己做出一个独裁的决定。阻力主要来自于他自己,而不是其他人。
不过,之所以会出现这种情况,也许跟他的预设立场有关:他似乎认为“Python is fine without a switch statement”,因此尽管写了很长的 PEP,但只是在把问题复杂化,把议题搁置起来。
最后,他在 PyCon 上做了一个小范围调查,借此“名正言顺”地拒绝了自己发起的 PEP,试图堵住众人的悠悠之口……
归结起来,之所以 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)。
截至 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 中国語 Web サイトの他の関連記事を参照してください。