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()
python实现访问者模式(递归方式)
最新推荐文章于 2024-05-02 08:11:01 发布