当前位置: 首页 > news >正文

眉山网站制作地方生活门户网站

眉山网站制作,地方生活门户网站,口碑好的品牌网站建设,电子商务网站开发项目假设要实现一个存放多种类型数据结构的对象#xff0c;比如一个存放算术操作数和操作符的树结点#xff0c;需要存放包含一元操作符、二元操作符和数字类型的结点 class Node:passclass UnaryOperator(Node):def __init__(self, operand):self.operand operandclass Binary…假设要实现一个存放多种类型数据结构的对象比如一个存放算术操作数和操作符的树结点需要存放包含一元操作符、二元操作符和数字类型的结点 class Node:passclass UnaryOperator(Node):def __init__(self, operand):self.operand operandclass BinaryOperator(Node):def __init__(self, left, right):self.left leftself.right rightclass Add(BinaryOperator):passclass Sub(BinaryOperator):passclass Mul(BinaryOperator):passclass Div(BinaryOperator):passclass Negative(UnaryOperator):passclass Number(Node):def __init__(self, value):self.value value 执行运算需要这样调用 # 假设运算式子2 - (22) * 2 / 1 2-(8) -6.0 t1 Add(Number(2), Number(2)) t2 Mul(t1, Number(2)) t3 Div(t2, Number(1)) t4 Sub(Number(2), t3)或者这样调用 t5 Sub(Number(2), Div(Mul(Add(Number(2), Number(2)), Number(2)), Number(1)))这样子需要执行多次类的调用极不易读写且冗长有没有一种方法让调用更加通用访问变得简单呢。这里使用访问者模式可以达到这样的目的。 访问者模式能够在不改变元素所属对象结构的情况下操作元素让调用或调用者caller的方式变得简单这种操作常见于的士公司操作当一个乘客叫了一辆的士时的士公司接收到了一个访问者并分配一辆的士去接这个乘客。 首先定义一个访问者结点类VisitorNode实现最基本的访问入口任何访问的方式都需要继承这个访问者结点类并通过这个访问者结点类的visit()方法来访问它的各种操作 # 访问者节点的基类 class NodeVisitor:def visit(self, node):if not isinstance(node, Node): # 不是Node对象时当做一个值返回如果有其他情况可以根据实际来处理return nodeself.meth visit_ type(node).__name__.lower() # type(node)也可以换成node.__class__只要node.__class__不被篡改meth getattr(self, self.meth, None) if meth is None:meth self.generic_visitreturn meth(node)def generic_visit(self, node):raise RuntimeError(fNo {self.meth} method)# 一种访问者对应的类 class Visitor(NodeVisitor):方法的名称定义都要与前面定义过的结点类Node的名称保证一致性def visit_add(self, node):return self.visit(node.left) self.visit(node.right)def visit_sub(self, node):return self.visit(node.left) - self.visit(node.right)def visit_mul(self, node):return self.visit(node.left) * self.visit(node.right)def visit_div(self, node):return self.visit(node.left) / self.visit(node.right)def visit_negative(self, node): # 如果class Negative 命名- class Neg那么 def visit_negative 命名- def visit_negreturn -self.visit(node.operand)def visit_number(self, node):return node.value这里的meth getattr(self, self.meth, None)使用了字符串调用对象方法self.meth动态地根据各类Node类Add, Sub, Mul…的名称定义了对应于类Visitor中的方法visit_add, visit_sub, visit_mul…简化了访问入口的代码当没有获取到对应的方法时会执行generic_visit()并抛出RuntimeError的异常提示访问过程中的异常 如果需要添加一种操作比如取绝对值只需要定义一个类class Abs(Unaryoperator): pass并在类Visitor中定义一个visit_abs(self, node)方法即可不需要做出任何多余的修改更不需要改变存储的结构 这里visit()方法调用了visit_xxx()方法而visit_xxx()可能也调用了visit()本质上是visit()的循环递归调用当数据量变大时效率会变得很慢且递归层次过深时会导致超过限制而失败而下面介绍的就是利用栈和生成器来消除递归提升效率的实现访问者模式的方法 import typesclass Node:passclass BinaryOperator(Node):def __init__(self, left, right):self.left leftself.right rightclass UnaryOperator(Node):def __init__(self, operand):self.operand operandclass Add(BinaryOperator):passclass Sub(BinaryOperator):passclass Mul(BinaryOperator):passclass Div(BinaryOperator):passclass Negative(UnaryOperator):passclass Number(Node):def __init__(self, value): # 与UnaryOperator区别仅命名不同self.value valueclass NodeVisitor:def visit(self, node):# 使用栈生成器来替换原来visit()的递归写法stack [node]last_result None # 执行一个操作最终都会返回一个值while stack:last stack[-1]try:if isinstance(last, Node):stack.append(self._visit(stack.pop()))elif isinstance(last, types.GeneratorType): # GeneratorType会是上一个if返回的对象这个对象会返回两个node执行算术之后的结果# 如果是生成器不pop掉而是不断send直到StopIteration# 如果last_result不是None这个值会给回到生成器例如2被visit_add()的左值接收到stack.append(last.send(last_result))last_result Noneelse: # 计算结果是一个值last_result stack.pop()except StopIteration: # 生成器yield结束stack.pop()return last_resultdef _visit(self, node):self.method_name visit_ type(node).__name__.lower()method getattr(self, self.method_name, None)if method is None:self.generic_visit(node)return method(node)def generic_visit(self, node):raise RuntimeError(fNo {self.method_name} method)class Visitor(NodeVisitor):def visit_add(self, node):yield (yield node.left) (yield node.right) # node.left和node.right都可能是Nodedef visit_sub(self, node):yield (yield node.left) - (yield node.right)def visit_mul(self, node):yield (yield node.left) * (yield node.right)def visit_div(self, node):yield (yield node.left) / (yield node.right)def visit_negative(self, node):yield -(yield node.operand)def visit_number(self, node):return node.value测试是否还会引起超过递归层数的异常 def test_time_cost():import times time.perf_counter()a Number(0)for n in range(1, 100000):a Add(a, Number(n))v Visitor()print(v.visit(a))print(ftime cost:{time.perf_counter() - s})输出正常没有问题 4999950000 time cost:0.9547078最后琢磨出了一个似乎可以作为替代的方法 class Node:passclass UnaryOperator(Node):def __init__(self, operand):self.operand operandclass BinaryOperator(Node):def __init__(self, left, right):self.left leftself.right rightclass Add(BinaryOperator):def __init__(self, left, right):super().__init__(left, right)self.value self.left.value self.right.valueclass Sub(BinaryOperator):def __init__(self, left, right):super().__init__(left, right)self.value self.left.value - self.right.valueclass Mul(BinaryOperator):def __init__(self, left, right):super().__init__(left, right)self.value self.left.value * self.right.valueclass Div(BinaryOperator):def __init__(self, left, right):super().__init__(left, right)self.value self.left.value / self.right.valueclass Negative(UnaryOperator):def __init__(self, operand):super().__init__(operand)self.value -self.operand.valueclass Number(Node):def __init__(self, value):self.value value运行测试 def test_time_cost():import times time.perf_counter()a Number(0)for n in range(1, 100000):a Add(a, Number(n))print(a.value)print(time.perf_counter() - s)输出 4999950000 0.2506986比前面的访问者模式还快而且不用递归- -!
http://www.pierceye.com/news/18159/

相关文章:

  • 通付盾 网站公司建设推广计划标题不允许重复
  • 做货代还有什么网站可以加人网络推广哪个好
  • 一元云购网站黑客攻击做网站是用ps还是ai
  • 杭州市建设银行网站搜外seo视频 网络营销免费视频课程
  • 网站建设做好了怎样链接域名英语网站 php源码
  • 教育网站制作公司旅游网页设计说明书
  • 做优化的网站用什么空间好织梦网站管理系统
  • 电子网站有哪些短视频代运营
  • 万网 网站建设方案书范文外贸网站建设厦门
  • 天津企业网站推广方法制作灯笼的手工做法步骤
  • 网站建设与管理专业就业织梦网站源文件没有style文件夹怎么修改网站背景
  • 网站建设实验原理动漫制作专业需要买电脑吗
  • 网站购物车建设王野摩托
  • 自由型网站天津百度搜索网站排名
  • 深圳网站建设模板乐云seo合肥网站建设公司代理
  • 鹤壁做网站价格脚气怎样治疗能根除
  • 普通电脑如何做网站服务器吗思源黑体 wordpress
  • 芜湖网站制作公司西安做网站建设的
  • 如何在一个地方建设网站上海it公司有哪些
  • 网站建设的标准化建设是什么qq群排名优化软件官网
  • 制作网站需要哪些成本十大网站在线观看
  • 做护肤品好的网站好wordpress批量增加文章
  • 专业建站流程2022年没封网站直接进入
  • 中国十佳企业网站设计公司百度seo网站优化
  • 做网站大概一个月多少工资深圳市住建局网站官网
  • 协会宣传网站开发方案一键logo设计网
  • 营销型外贸网站定制制作网页时采用的最基本的语言是
  • 品牌网站运营教育咨询
  • 单页网站怎么做外链wordpress提高阅读量
  • 校区网站建设小程序制作开发如意推