switch 擬で記述すると

expr = "3 4 +"
expr = "3 4 + 2 *"

parser = Parser()
cal = Polish()
for e in expr.split(" "):
    e = parser.scan(e)
    e.switch({
        Value: cal.value,
        Op   : cal.op,
        })
print cal.evaluate()
# --------------------------

class Polish:
    def __init__(self):
        self.stack = []

    def value(self, e):
        self.stack.append(e)

    def op(self, e):
        op2 = self.stack.pop()
        op1 = self.stack.pop()
        value = eval("%s %s %s"%(op1, e, op2))
        self.stack.append(value)

    def evaluate(self):
        return self.stack.pop()

# --------------------------
class Token:
    def __repr__(self):
        return "%s"%self.value

    def switch(self, dispatch):
        return dispatch[self.__class__](e)

class Value(Token):
    def __init__(self, value):
        self.value = int(value)
        
class Op(Token):
    def __init__(self, value):
        self.value = str(value)        
    
# --------------------------

ポリモフィズムを利用すると

前述したように、if と別れる「始め一歩」がポリモフィズムの導入を検討してみることです。それが「末の千里」へと誘います。

expr = "3 4 +"
expr = "3 4 + 2 *"

parser = Parser()
cal = Polish()
for e in expr.split(" "):
    e = parser.scan(e)
    e.evaluate(cal)
    
print cal.evaluate()

ポリモフィズムを利用すると、switch 擬と比べて、簡潔で見通しの良いコードを記述できます。要求仕様の変更にも柔軟に対処できるだけでなく、動的スキーマの適用が可能になります。

# --------------------------
class Token:
    def __repr__(self):
        return "%s"%self.value

    def switch(self, dispatch):
        return dispatch[self.__class__](e)

class Value(Token):
    def __init__(self, value):
        self.value = int(value)

    def evaluate(self, cal):
        cal.value(self)
        
class Op(Token):
    def __init__(self, value):
        self.value = str(value)        

    def evaluate(self, cal):
        cal.op(self)

# --------------------------

クラス:Parser

まず、組み込み関数 filter のヘルプ情報を確認します。

class Parser:
    def scan(self, e):
        s = e
        if e in "+-*/":
            s = Op(e)     # 演算子: operator
        else:
            s = Value(e)  # 被演算子(引数): operand)
        return s

逆ポーランド記法で書かれた式(文字列)を調べて、演算子と被演算子(引数)とを判別します。

《こちらに移動中です》
Python.use(better) 記事一覧
ifと別れる50の方法
《7》switchは百害あって一理なし

《著》後藤いるか・森こねこ《監修》小泉ひよ子とタマゴ倶楽部
第0版♪1988/03/30 ● 第1版♪2000/05/23 ● 更新♪2008/11/22