0

簡単なパーサーを書いているとします。入力式のタイプに応じて、対応する解析関数を呼び出すディスパッチャがあります。

def dispatcher(expression):
    m = pattern1.match(expression):
    if m is not None:
        handle_type1(expression, m)
    # ... other types

私の質問は、マッチングとチェックを組み合わせる方法はありNoneますか? つまり、次の C コードのようなものです。

void dispatcher(char *expression)
{
    if ((m = pattern1.match(expression)) != NULL) {
        // ... handle expression type 1
    }
    else if ((m = pattern2.match(expression)) != NULL) {
        // ... handle expression type 2
    }
    // ... other cases
}

ありがとう!

4

4 に答える 4

5

これは実際には、パターン マッチングと何もチェックしないことを組み合わせることではなく、変数に割り当てて、その割り当ての結果を 1 つの式で評価できるかどうかに関するものです。

Python では代入は statementであり、C のように式ではないため、一般的な答えはノーです。

この場合の唯一の違いは、余分なキャリッジ リターンを節約できることです。これはあまり役に立ちません。割り当てと比較のイディオムはループでより便利ですが、Python では 2 行で実行するだけです (必要に応じて break を使用します)。

于 2012-10-29T13:19:17.357 に答える
3

あなたの C ライクな例は少し反復的だと思いませんか? コードを何度も繰り返している場合は、ループに置き換えることを検討してください。このようなものは、マッチとテストの重複を避けます:

def dispatcher(expression):
    for pattern, action in [
        (pattern1, handle_type1),
        (pattern2, handle_type2),
        ]:
        m = pattern.match(expression):
        if m is not None:
           action(expression, m)
           break

また、さまざまな方法でパターンとハンドラーのリストをループから引き出すこともできます。たとえば、ハンドラーがすべて同じクラスのメソッドである場合、デコレーターを定義して、ハンドラーの横に定義されたパターンでリストを自動的に構築できます。

@patternhandler('some regex')
def handle_type1(expression, match):
    ...
于 2012-10-29T13:32:14.333 に答える
2

あなたができる最善の方法は、作業を行うためのクラスを作成することです。その後、クラスは最後に一致したパターンなどの状態を維持できます。

class Matcher(object):
    def __init__(self):
        self.m = None

    def match(self, pattern, text):
        self.m = re.match(pattern, text)
        return self.m


def dispatcher(expression):
    matcher = Matcher()
    if matcher.match(pattern1, expression):
        handle_type1(expression, matcher.m)
    if matcher.match(pattern2, expression):
        handle_type2(expression, matcher.m)
于 2012-10-29T13:31:04.750 に答える