python实现访问者模式(递归方式)

class Node:
    """ 节点类 """
    pass

class UnaryOperator(Node):
    """ 一元操作符类 """
    def __init__(self, operand):
        self.operand = operand
    
class BinaryOperator(Node):
    """ 二元操作符类 """
    def __init__(self, left, right):
        self.left = left
        self.right = right

class Number(Node):
    """ 数字类 """
    def __init__(self, value):
        self.value = value

class Negate(UnaryOperator):
    """ 取反类 """
    pass

class Add(BinaryOperator):
    """ 加法类 """
    pass

class Sub(BinaryOperator):
    """ 减法类 """
    pass

class Mul(BinaryOperator):
    """ 乘法类 """
    pass

class Div(BinaryOperator):
    """ 除法类 """
    pass

class NodeVisitor:
    """ 访问者类 """
    def visit(self, node):
        # 根据节点名获取对应处理方法
        meth_name = 'visit' + type(node).__name__
        # 将获取到的方法绑定到 meth
        meth = getattr(self, meth_name, None)
        # 如果没有对应方法,则将回退方法绑定到 meth
        if meth is None:
            meth = self.regression
        # 返回 meth 方法调用的结果
        return meth(node)

    def regression(self, node):
        # 回退方法,抛出运行时异常
        raise RuntimeError('no such method {}'.format('visit' + type(node).__name__))

class Executor(NodeVisitor):
    """ 执行者类 """
    def visitNumber(self, node):
        # 访问数字节点,直接返回其值
        return node.value
    def visitNagate(self, node):
        # 访问取反节点,返回值的相反数
        return -node.value
    def visitAdd(self, node):
        # 访问加法节点,返回对左右两个操作数分别访问结果的和
        return self.visit(node.left) + self.visit(node.right)
    def visitSub(self, node):
        # 访问减法节点,返回对左右两个操作数分别访问结果的差
        return self.visit(node.left) - self.visit(node.right)
    def visitMul(self, node):
        # 访问乘法节点,返回对左右两个操作数分别访问结果的积
        return self.visit(node.left) * self.visit(node.right)
    def visitDiv(self, node):
        # 访问除法节点,返回对左右两个操作数分别访问结果的商
        return self.visit(node.left) / self.visit(node.right)

def main():
	t1 = Sub(Number(2), Number(1))
	t2 = Mul(Number(3), t1)
	t3 = Add(Number(5), t2)
	t4 = Div(t3, Number(5))
	# t4 = ((5 + (3 * (2 - 1))) / 5) = 1.6
	executor = Executor()
    # 使用执行者访问节点 t4,并打印结果
	print(executor.visit(t4))

if __name__ == "__main__":
    main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值