“
この記事を読むのに約10分かかります。
”
この記事では、Pythonがswitchステートメントをサポートしないことにした理由について説明します。
なぜこのトピックについて話したいのですか?
主な理由は、スイッチが他の言語では一般的すぎるためですが、Pythonはそれをサポートしていません。この独自性自体は注目に値します。この質問に答えることで、プログラミングにおけるPythonの概念をより明確に理解し、Pythonの文法設計を理解することもできます。意思決定プロセスにおいて。
この記事では、PEP-275とPEP-3103の詳細な分析に加えて、Pythonの最新の開発(PEP-622)、つまり導入される可能性のあるパターンマッチング構文についても紹介します。このトピックは、すべての人の視野を広げると思います。スイッチの文法をより包括的に理解するために。
トピックを始める前に、スイッチとは何かについて話す必要がありますか?
一部の学生はそれを初めて考えるかもしれません...
ねえ〜ねえ〜、気をつけてください、いつもゲームについて考える必要はありません。プログラミング言語でのスイッチステートメントについて話します。
一般的に、switchの構文形式は次のとおりです。
switch(expression){case value1://ステートメントブレーク;//オプションのケース値2://ステートメントブレーク;//オプションのデフォルト://オプション//ステートメント}
フローチャートを使用して表現すると、次のようになります。
その使用法を理解するのは難しいことではありません。switchステートメントの値が満たされる場合、対応するコードブロックが実行され、実行中にブレークが発生するとジャンプします。それ以外の場合は、次のcaseブランチを実行し続けます。通常、デフォルトのブランチは最後に配置されます。 、ポケットの底として。
ほとんどの言語は、switchステートメントまたは非常に類似したものを提供します。たとえば、C / C ++ / Java / Goなどの静的言語では、すべてswitch-case構造をサポートします。Rubyでは、同様のcase-when構造がShellにあります。言語には、同様のケースイン構造があり、Perlには、switch-case-elseがあります...
switchステートメントの利点は、「単一条件および複数ブランチ」選択構造をサポートすることです。if-elseバイナリ選択構造と比較すると、場合によってはより簡潔で明確になります。
ただし、Pythonでは、switch-caseまたは同様の文法構造を確認できません。それはなぜですか。
この質問を含む公式ドキュメントにFAQがあります:なぜPythonにswitchまたはcaseステートメントがないのですか?
FAQは、よくある質問の略で、よくある質問を意味します。27のよくある質問の公式リストは、次のとおりです。
このドキュメントは、いくつかの提案を提供し、いくつかのスイッチ/ケースの代替案を示しています。
Pythonにスイッチ構文を導入したいという提案(PEP-275やPEP-3103など)がいくつかありますが、「範囲テストを実施するかどうか」についてはコンセンサスがありません。
レンジテスト、またはレンジテストは、武器や弾薬の技術的性能を検証するためのさまざまなテストを指します。薬物の臨床試験と同様に、最終製品が納品される前の重要なテストです。
「Pythonがスイッチを導入しない理由」に関する公式文書の説明は、実際には、PEP-3103のPythonの父であるGuido vanRossumの意見に基づいています。
出典:https://www.python.org/dev/peps/pep-3103
A quick poll during my keynote presentation at PyCon 2007 shows this proposal has no popular support. I therefore reject it.
PyCon 2007の基調講演で簡単な調査を行ったところ、この提案は広く支持されていなかったことがわかりました。したがって、私はそれを拒否しました。
要するに、** PEP提案があり、文法の実装は基本的な形式ですが、コア開発者は合意に達していないようで、最終的に提案は中止されました。 ****
PEP-3103は2006年に提案され、PEP-275は2001年に提案されました。共通しているのは、スイッチステートメントを導入する必要性を提唱し、いくつかの代替実装スキームを分析したことです。 、エンディングは拒否されます。
出典:https://www.python.org/dev/peps/pep-0275
それでは、最初にコア開発者が行った議論を確認し、Pythonがスイッチ構造を実装した場合に何が起こるかを見てみましょう。 (PS:PEPには他のコンテンツも含まれます。この記事では、スイッチに直接関連する部分のみを抽出します)
PEP-275によって提案された文法構造は次のとおりです。
switch EXPR:case CONSTANT:
SUITE
case CONSTANT:
SUITE
... else:
SUITE
elseブランチはオプションです。存在せず、前のブランチが満たされない場合、何も実行されません。さらに、expr式のタイプは動的であるため、ケース値定数はさまざまなタイプをサポートします。
PEP-275は、スイッチがフォールスルー動作をサポートしないことも提案しています。つまり、各ケースブランチは独立していて完全であり、C言語のようにブレークを記述する必要はありません。
PEPには、その他の問題もいくつか記載されています。
推奨されるスキームに加えて、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の2つの基本設定、たとえば、制御を転送するケースブランチのフォールスルーを防ぐための「暗黙のブレーク」の実現を認識しました(他の言語では明示的な書き込みが必要なようです) break); elseブランチはオプションです。「default」を導入する代わりに、elseキーワードを再利用してください。
Guidoは、PEP-275が提唱するスタイルに同意しますが、問題はインデントのレベルが多すぎることでもあると考えています。したがって、コードブランチインデントのスペース数を減らすことをお勧めします。たとえば、元のインデントは4スペースで、インデント2に変更されます。スペース。
PEP-3103には、他の3つの実装スキームもリストされており、それらの違いと問題が分析されています。特定のコンテンツは省略されています。ここでは、それらのスタイルを示します。
# ケースブランチはインデントされていません
switch EXPR:case EXPR:
SUITE
case EXPR:
SUITE
.... else:
SUITE
# switchステートメントの後にコロンがありません
switch EXPR
case EXPR:
SUITE
case EXPR:
SUITE
.... else:
SUITE
# ケースキーワードを省略
switch EXPR:
EXPR:
SUITE
EXPR:
SUITE
... else:
SUITE
基本的な構文に加えて、Guidoは拡張構文(拡張構文)、つまりケースブランチで複数の値を照合する複雑な状況について議論するために多くのスペースを費やしました:
case EXPR, EXPR,...:
# Guidoが好ましい
casein EXPR_LIST:case*EXPR:case[*]EXPR,[*]EXPR,...:case*(EXPR, EXPR,...):
彼が検討した重要な問題には、switchの式の結果がタプルまたは反復可能なオブジェクトである場合、ケースの値がタプルの解凍として扱われる場合、およびケースブランチの「*」アスタリスク操作が含まれます。
次に、Guidoは、スイッチの実装方法を分析するために多くのスペースを費やしました。そこで説明されている主なアイデアは次のとおりです。
PEPのこの部分には多くのコンテンツがあります。これは、Guidoが各アイデアのいくつかの実装パスも検討したため、複雑な分析の結果、次のように結論が出されたためです。早い)。
PEP-3103を読んだ後、私の全体的な感覚は次のとおりです。Guidoの考えは非常に多様で、層が豊富ですが、他の問題に直面したときの「クイックノックスルー」の洞察が欠けています。
言い換えれば、多くの可能な解決策の中で、彼はすべてをカバーしようと努めており、最終的には独裁的な決定を下すように自分を納得させることはできません。抵抗は主に自分自身から来ており、他人からではありません。
ただし、この状況の理由は、デフォルトの位置に関連している可能性があります。彼は「Pythonはswitchステートメントがなくても問題ない」と考えているため、長いPEPを作成しましたが、問題を複雑にして変更しているだけです。問題は保留されました。
最後に、彼はPyConに関する小規模な調査を実施しました。これにより、彼は開始したPEPを「正当に」拒否し、すべての人ののんびりとした口をブロックしようとしました...
最終的な分析では、Pythonにswitchステートメントがない理由は次のとおりです。** switchの実装の詳細/機能は確定されていません。switchがなくても問題ありません。また、switchとGuidoのわずかな意図を置き換える他の良い方法があります...... **
ただし、まだ質問する必要があります。将来、切り替えステートメントはありますか?または同様のマルチブランチ選択構造? ****
なぜそのような質問があるのですか?その理由は、あまりにも多くの言語が独自のスイッチステートメントを持っており、多くの人がスイッチ機能を提供するライブラリを書き込もうとしているためです(* PyCoder's Weekly *で2回見たことを覚えています)。
私(Python cat)は、最初から最後まで切り替えるのが好きではありませんでした。Pythonに将来的に切り替えがないことはほぼ確実ですが、switchに似たより複雑な文法構造が導入される可能性があります。
2020 2008年6月にPEP-622が提案され、Scala、Erlang、Rustなどの言語でパターンマッチング構文(パターンマッチング)を導入することが提案されました。
2020年10月の時点で、PEPは他の3つのPEP(634-636)に分割されており、それらはすべて現在ドラフト段階にあります。コア開発者の参加とトピックの議論を考慮すると、これらの提案は将来のバージョン(開発中の3.10など)で実装される可能性が最も高いです。
平均関数を例にとると、パターンマッチング構文は次のように実装できます。
def average(*args):
match args:case[x, y]: # captures the two elements of a sequence
return(x + y)/2case[x]: # captures the only element of a sequence
return x
case[]:return0case x: # captures the entire sequence
returnsum(x)/len(x)
マッチケース構造はスイッチケース構造に似ていますが、式ではなくパターンに基づいているため、考慮すべき詳細が多く、アプリケーションスペースが広くなっています。
このトピックに関心のある読者は、これらの新しいPEPを確認することをお勧めします。
最後に、タイトルの質問に戻りましょう。** Pythonがswitchステートメントをサポートしないのはなぜですか? ****
公式文書のFAQには、この質問に対する回答があり、いくつかの優れた代替案があり、手がかりも残されています。PEPはかつてスイッチの導入を提案しましたが、正常に実装されませんでした。
この手がかりに続いて、この記事では2つのドキュメントPEP-275とPEP-3103を分解し、Pythonコミュニティで提案されているさまざまなスタイルのスイッチソリューションと、多くの未解決の問題を示しました。
最後に、最新のPEP-622ダイナミクスにも注目しました。スイッチの「ツインブラザー」マッチ構文がPythonに導入されることが期待されているようです。スイッチトピックに関する議論は終了しているようですが、別のより大きなトピックが進行中です!
Recommended Posts