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

网站建设服务器介绍图片湘潭做网站广告的公司

网站建设服务器介绍图片,湘潭做网站广告的公司,泉州做网站seo,聊城 网站制作目录 基本概念节点类型ast.Assignast.Nameast.Constantast.Callast.Attribute 结点的遍历ast源码示例 结点的修改示例 参考链接 基本概念 在 python 中#xff0c;我们可以通过自带的 ast 模块来对解析遍历语法树#xff0c;通过ast.parse()可以将字符串代码解析为抽象语法树… 目录 基本概念节点类型ast.Assignast.Nameast.Constantast.Callast.Attribute 结点的遍历ast源码示例 结点的修改示例 参考链接 基本概念 在 python 中我们可以通过自带的 ast 模块来对解析遍历语法树通过ast.parse()可以将字符串代码解析为抽象语法树然后通过ast.dump()可以打印这棵语法树。 除了ast模块外还有 astor 模块其中的 astor.to_sourse() 函数可以将语法树Node转换为代码 astor.dump_tree() 可以很好地格式化整棵树。 除了这些基础操作外我们还可以遍历和修改整棵语法树。 比如对于a 10 来说我们可以先解析成抽象语法树然后打印所有的结点如下所示。根据输出我们可以看到根节点是Module类型的然后其body是Assign类型的。对于Assign类型的结点可以继续划分为Name结点表示变量名和Constant结点表示变量内容。 node ast.parse(a 10) print(astor.dump_tree(node)) # Module(body[Assign(targets[Name(ida)], valueConstant(value10, kindNone), type_commentNone)], type_ignores[])节点类型 上面的简单示例向我们展示了几种基本结点类型Assign、Name、Constant接下来我们将会展示其他几种常见的结点类型和示例完整的节点类型可以查阅节点类型。大体上我们可以把结点类型分为叶子结点类型和非叶子结点类型比如Assign就是非叶子结点类型Name和Constant是叶子结点类型因为他们不会有子结点了。 ast.Assign Assign 类型用来表示赋值语句比如a 10、 b a 这样的赋值语句都是Assign结点类型他并不是一个叶子结点因为它的下面一般还有 Name 结点。 ast.Name Name类型用来表示一个变量的名称是一个叶子结点。比如对于b a 这样的赋值语句子结点就是两个Name。 node ast.parse(a b) print(astor.dump_tree(node.body[0])) # Assign(targets[Name(ida)], valueName(idb), type_commentNone)ast.Constant 表示一个不可变内容它可以是Number 、string只要其内容是不可变的都是ast.Constant类型的结点它是一个叶子结点。 node ast.parse(a 100) print(astor.dump_tree(node.body[0])) # Assign(targets[Name(ida)], valueConstant(value100, kindNone), type_commentNone)node ast.parse(a paddle) print(astor.dump_tree(node.body[0])) # Assign(targets[Name(ida)], valueConstant(valuepaddle, kindNone), type_commentNone)ast.Call 表示函数的调用比如paddle.to_tensor()。非叶子节点类型一般包含三个属性func、args、 keywords。 func代表调用函数的名称一般是一个ast.Name或ast.Constant类型的结点如果是连续调用会是一个ast.Call结点。args代表函数传入的位置参数和可变参数。keywords代表函数传入的关键字参数。 node ast.parse(paddle.to_tensor(1, a 10)) print(astor.dump_tree(node.body[0]))# Expr(valueCall(funcAttribute(valueName(idpaddle), attrto_tensor),args[Constant(value1, kindNone)],keywords[keyword(arga, valueConstant(value10, kindNone))]))对于上面的例子我们通过可视化可以看到顶层是一个ast.Expr类型的结点表示一个表达式。下面是ast.Call 结点Call 结点包含 一个ast.Attribute结点表示调用者和调用的方法名paddle是调用者to_tensor是方法名一个ast.Constant类型的args表示函数的位置参数一个ast.keyword表示函数的关键字参数。 下面我们看一个比较复杂的示例多个函数的连续调用。根据输出结果可以看到最后的调用reshape在最外层然后一直向内递归子结点还是ast.Call类型的结点。 node ast.parse(a.to_tensor(1, a 10).reshape(1)) print(astor.dump_tree(node.body[0]))Expr(valueCall(funcAttribute(valueCall(funcAttribute(valueName(ida), attrto_tensor), args[Constant(value1, kindNone)],keywords[keyword(arga, valueConstant(value10, kindNone))]),attrreshape),args[Constant(value1, kindNone)],keywords[]))ast.Attribute 上面的例子中出现了ast.Attribute结点Attribute结点可以理解为属性是一个非叶子结点。它包含两个字段value字段和attr字段。对于a.shape来说value指明调用者即aattr指明调用的方法名即shape。 node ast.parse(a.shape) print(astor.dump_tree(node.body[0]))Expr(valueAttribute(valueName(ida), attrshape))结点的遍历 在ast模块中可以借助继承ast.NodeVisitor类来完成结点的遍历该类具有两种访问结点的方法一种是针对所有结点类型通用的访问方法generic_visit()另一种是针对某个类型结点的访问方法 visit_xxx其中xxx代表具体的结点类型。generic_visit()函数是遍历每个结点的入口函数随后会调用visitor()函数获取该结点的类型然后判断是否有遍历该类型结点的函数如果有则调用 visit_xxx类型的方法如果没有则调用通用generic_visit()方法。 ast源码 class NodeVisitor(object):def visit(self, node):Visit a node.method visit_ node.__class__.__name__visitor getattr(self, method, self.generic_visit)return visitor(node)def generic_visit(self, node):# 可以看到 generic_visit函数会调用visit函数然后寻找并调用特定类型的visit函数。 Called if no explicit visitor function exists for a node.for field, value in iter_fields(node):if isinstance(value, list):for item in value:if isinstance(item, AST):self.visit(item)elif isinstance(value, AST):self.visit(value)def visit_Constant(self, node):value node.valuetype_name _const_node_type_names.get(type(value))if type_name is None:for cls, name in _const_node_type_names.items():if isinstance(value, cls):type_name namebreakif type_name is not None:method visit_ type_nametry:visitor getattr(self, method)except AttributeError:passelse:import warningswarnings.warn(f{method} is deprecated; add visit_Constant,PendingDeprecationWarning, 2)return visitor(node)return self.generic_visit(node)示例 下面是一个例子我们定义了一个继承ast.NodeVisitor的类并且重写了visit_attribute方法这样在遍历到ast.Attribute结点时会输出当前调用的属性名或方法名对于其他类型的结点则会输出结点类型。 class CustomVisitor(ast.NodeVisitor):def visit_Attribute(self, node):print(---- node.attr)ast.NodeVisitor.generic_visit(self, node)def generic_visit(self, node):print(node.__class__.__name__)ast.NodeVisitor.generic_visit(self, node)code textwrap.dedent(import paddlex paddle.to_tensor([1, 2, 3])axis 0y paddle.max(x, axisaxis) ) node ast.parse(code) visitor CustomVisitor() visitor.generic_visit(node)需要注意的是当我们重写visit_xxx函数后一定要记得再次调用ast.NodeVisitor.generic_visit(self, node)这样才会继续遍历整棵语法树。 结点的修改 对于结点的修改可以借助ast.NodeTransformer 类来完成ast.NodeTransformer继承自ast.NodeVisitor类重写了generic_visit方法该方法可以传入一个结点并且返回修改后的结点从而完成语法树的修改。 示例 在该示例中我们定义了CustomVisitor类来修改ast.Call 结点。具体来说当遍历到Call类型的结点后流程如下 首先会调用get_full_attr方法获取整个api名称如果是普通方法调用则会返回完整的调用名称比如torch.tensor()会返回torch.tensor如果是连续的方法调用比如x.exp().floor()则会返回ClassMethod.floor。然后调用 ast.NodeVisitor.generic_visit(self, node) 进行深度优先的修改这样就可以一层层递归先修改内层再修改外层。如果是普通的方法调用则修改结点后返回如果是连续的方法调用需要先通过astor.to_source(node)获取前缀方法即调用者保留前缀方法名称的同时修改目前的方法名后返回。具体是通过{}.{}()实现的。 def get_full_attr(node):# torch.nn.fucntional.reluif isinstance(node, ast.Attribute):return get_full_attr(node.value) . node.attr# x.abs() - xelif isinstance(node, ast.Name):return node.id# for example ast.Callelse:return ClassMethodclass CustomVisitor(ast.NodeTransformer):def visit_Call(self, node):# 获取api的全称full_func get_full_attr(node.func)# post orderast.NodeVisitor.generic_visit(self, node)# 如果是普通方法调用直接改写整个结点即可if full_func torch.tensor:# 将 torch.tensor() 改写为 paddle.to_tensor()code paddle.to_tensor()new_node ast.parse(code).body[0]return new_node.value# 如果是类方法调用需要取前面改写后的方法作为 func.value if full_func ClassMethod.floor:# 获取前缀方法作为 func.valuenew_func astor.to_source(node).strip(\n)new_func new_func[0: new_func.rfind(.)]# 将 floor() 改写为 floor2()code {}.{}().format(new_func, floor2)new_node ast.parse(code).body[0]return new_node.value# 其余结点不修改return nodecode textwrap.dedent(import torchx torch.tensor([1, 2, 3])x x.exp().floor() ) node ast.parse(code) visitor CustomVisitor() node visitor.generic_visit(node) result_code astor.to_source(node) print(result_code)参考链接 https://blog.csdn.net/ThinkTimes/article/details/110831176?ydrefereraHR0cHM6Ly9jbi5iaW5nLmNvbS8%3D https://greentreesnakes.readthedocs.io/en/latest/ https://github.com/PaddlePaddle/PaConvert
http://www.hkea.cn/news/14416827/

相关文章:

  • 金阊公司网站建设电话怎样在国外网站上做外贸广告
  • 百合网网站建设与策划wordpress怎么备份
  • 郑州网站推广方案网站建设流程 文档
  • 电子商务网站包括怎么样用手机做网站关键词
  • 公司的宣传网站应该怎么做小程序开发平台官网入口
  • 建设网站公司怎么建站代写文章平台
  • 网站网站开发者犯法吗室内装饰公司网站模板
  • 网站优化的方式有哪些wordpress 中文转英文js
  • 做民宿哪家网站最好网站开发使用技术第二版答案
  • 国外电子政务j建设与我国电子政务网站建设对比海南新政策最新
  • 建立个人免费网站wordpress apache版本号
  • 建站之星做的网站如何导出网站制作商
  • 兰州网站制作有哪些商务网站设计与制作
  • 网站建设需什么软件网站开发过程中出现的问题
  • 网站建设 微信小程序大芬地铁站附近做网站
  • 一个公司多个网站做优化很看好未来做生鲜的网站
  • 手机网站的视频怎么才能下载西安专业网站开发公司
  • 规划馆网站建设搜索引擎优化百度
  • 做室内3d设计的网站福州网吧
  • 上海市区网站设计制作公司注册公司流程图
  • 做网站就是做服务wordpress如何用
  • 怎么上线网站小说网站架构
  • 科技公司网站系统手机怎么自己设计图片
  • 慈溪建设银行支行网站做任务赚佣金的网站
  • 网站规划详细设计怎么写linux服务器wordpress建站教程视频
  • 长沙交互网站设计服务商网站开发去哪里培训
  • 网站开发工作好吗课程设计代做网站
  • 个人网站备案费用php网站开发试题及答案
  • 电子元器件网站怎么做对seo的理解
  • 电商免费网站入口网络广告推广方案