サーチ…


備考

言語設計上の選択としてPythonでのNOスイッチ文はありません。拒絶された話題をカバーするPEP( PEP-3103 )がありました。

Pythonで独自のswitch文を実行する方法に関するレシピのリストがたくさんあります。ここでは、最も賢明なオプションを提案しようとしています。確認する場所は次のとおりです。

言語が提供するものを使用してください:if / else構造体。

さて、 switch / case構造体が必要な場合は、古いold if / else構造体を使用するのが最も簡単な方法else

def switch(value):
    if value == 1:
        return "one"
    if value == 2:
        return "two"
    if value == 42:
        return "the answer to the question about life, the universe and everything"
    raise Exception("No case found!")

それは冗長に見えるかもしれませんが、いつもかわいいとは限りませんが、これははるかに効率的な方法です。

>>> switch(1)
one
>>> switch(2)
two
>>> switch(3)
…
Exception: No case found!
>>> switch(42)
the answer to the question about life the universe and everything

関数の辞書を使う

もう一つの簡単な方法は、関数の辞書を作成することです。

switch = {
    1: lambda: 'one',
    2: lambda: 'two',
    42: lambda: 'the answer of life the universe and everything',
}

デフォルト関数を追加します:

def default_case():
    raise Exception('No case found!')

辞書のgetメソッドを使用して、値を与えられた関数を取得してチェックして実行します。 valueが辞書に存在しない場合、 default_caseが実行されます。

>>> switch.get(1, default_case)()
one
>>> switch.get(2, default_case)()
two
>>> switch.get(3, default_case)()
…
Exception: No case found!
>>> switch.get(42, default_case)()
the answer of life the universe and everything

あなたは構文的な砂糖を作ってスイッチがより良く見えるようにすることもできます:

def run_switch(value):
    return switch.get(value, default_case)()

>>> run_switch(1)
one

クラスのイントロスペクションを使用する

クラスを使用して、スイッチ/ケース構造を模倣することができます。以下は、文字列をインスタンス上のバインドされたメソッドに解決するgetattr()関数を使用してクラスのイントロスペクションを使用して、 "case"部分を解決します。

そのイントロスペクティングメソッドは、 __call__メソッドにエイリアスされて、 ()演算子がオーバーロードされます。

class SwitchBase:
    def switch(self, case):
        m = getattr(self, 'case_{}'.format(case), None)
        if not m:
            return self.default
        return m

    __call__ = switch

次に、それを見栄え良くするために、 SwitchBaseクラスをサブクラス化しSwitchBase (ただし、1つのクラスで行うことができます)。すべてのcaseをメソッドとして定義します。

class CustomSwitcher:
    def case_1(self):
        return 'one'

    def case_2(self):
        return 'two'

    def case_42(self):
        return 'the answer of life, the universe and everything!'

    def default(self):
        raise Exception('Not a case!')

それで私たちは最終的にそれを使うことができます:

>>> switch = CustomSwitcher()
>>> print(switch(1))
one
>>> print(switch(2))
two
>>> print(switch(3))
…
Exception: Not a case!
>>> print(switch(42))
the answer of life, the universe and everything!

コンテキストマネージャを使用する

非常に読みやすく優雅ですが、if / else構造よりはるかに効率的でないもう1つの方法は、次のようなクラスを構築し、それを比較して値を保存し、コンテキスト内で呼び出し可能なものとして公開します格納された値と一致する場合はtrueを返します。

class Switch:
    def __init__(self, value): 
        self._val = value
    def __enter__(self):
        return self
    def __exit__(self, type, value, traceback):
        return False # Allows traceback to occur
    def __call__(self, cond, *mconds): 
        return self._val in (cond,)+mconds

ケースを定義することは、実際のswitch / caseコンストラクト(以下の関数の中で公開するほうが簡単です)にほぼ一致しています。

def run_switch(value):
    with Switch(value) as case:
        if case(1):
            return 'one'
        if case(2):
            return 'two'
        if case(3):
            return 'the answer to the question about life, the universe and everything'
        # default
        raise Exception('Not a case!')

実行は次のようになります。

>>> run_switch(1)
one
>>> run_switch(2)
two
>>> run_switch(3)
…
Exception: Not a case!
>>> run_switch(42)
the answer to the question about life, the universe and everything

ノートベネ



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow