python 通过 ast 替换代码

导航目录

      • 目录结构
      • 要替换的代码
      • 替换代码的逻辑
        • 新建类,继承 ast
        • 运行新建的类
        • 最最重要的一步
        • replace_code.py 完整代码
      • main.py 里面的代码
      • 执行结果
    • 最后

目录结构

.
├── hello
│   ├── __init__.py
│   └── utils.py
├── main.py
├── replace_code.py

要替换的代码

代码在文件 utils.py 里面

def sum(a: int, b: int) -> int:c = a - breturn c

替换代码的逻辑

替换代码逻辑在文件 replace_code.py 里

新建类,继承 ast

逻辑很简单:找到哪一行并替换,就是中间的判断可能比较多

import ast
class MyTransformer(ast.NodeTransformer):def visit(self, node: ast.AST):# 我们要找到要替换的那一行('c = a - b')代码在哪里for nodei, v in enumerate(node.body):if isinstance(v, ast.FunctionDef):for i, vv in enumerate(v.body):if isinstance(vv, ast.Assign) and \isinstance(vv.value, ast.BinOp) and \isinstance(vv.value.left, ast.Name) and \vv.value.left.id == 'a' and vv.value.right.id == 'b' and isinstance(vv.value.op, ast.Sub):# 找到了那一行代码# 找到后把新的代码通过 ast.parse 转换成语法树,并替换掉原来的代码v.body[i] = ast.parse('c = a + b').body[0]node.body[nodei] = vreturn node
运行新建的类
from hello import utils
import inspect
# 获取代码内容
method_code = inspect.getsource(utils.sum)
print(f'----sum code begin\n {method_code} \n -----sum code end ----')
# 把要替换的代码转换成语法树
method_ast = ast.parse(method_code)
trans_instance = MyTransformer()
# 运行新建的类的里面的逻辑
transformed_ast = trans_instance.visit(method_ast)
# 把语法树解析成语法代码
transformed_code = ast.unparse(transformed_ast)
print('--- transformed code:', transformed_code)
最最重要的一步

一定要把代码在它所在的命名空间里执行它

exec(transformed_code, utils.__dict__)
replace_code.py 完整代码
import ast
class MyTransformer(ast.NodeTransformer):def visit(self, node: ast.AST):for nodei, v in enumerate(node.body):if isinstance(v, ast.FunctionDef):for i, vv in enumerate(v.body):if isinstance(vv, ast.Assign) and \isinstance(vv.value, ast.BinOp) and \isinstance(vv.value.left, ast.Name) and \vv.value.left.id == 'a' and vv.value.right.id == 'b' and isinstance(vv.value.op, ast.Sub):print('here')v.body[i] = ast.parse('c = a + b').body[0]node.body[nodei] = vreturn node
from hello import utils
import inspect
method_code = inspect.getsource(utils.sum)
print(f'----sum code begin\n {method_code} \n -----sum code end ----')
method_ast = ast.parse(method_code)
trans_instance = MyTransformer()
transformed_ast = trans_instance.visit(method_ast)
transformed_code = ast.unparse(transformed_ast)
print('--- transformed code:', transformed_code)
exec(transformed_code, utils.__dict__)

main.py 里面的代码

导入的顺序一定不要错了,不然也不会生效的

# 引入的顺序一定不要错了,不然也不会生效的
import replace_code
from hello.utils import sum
if __name__ == '__main__':print(sum(2,1))

执行结果

----sum code begindef sum(a: int, b: int) -> int:c = a - breturn c-----sum code end ------- transformed code: def sum(a: int, b: int) -> int:c = a + breturn c
3 # 这是执行后的结果

最后

逻辑代码不一定要在 visit() 里面写,如果你要修改的是 for 循环里面的代码 你可以重写 visit_For()方法, 在里面来实现自己的逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/753753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【开源】SpringBoot框架开发毕业生追踪系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登陆注册模块2.2 学生基本配置模块2.3 就业状况模块2.4 学历深造模块2.5 信息汇总分析模块2.6 校友论坛模块 三、系统设计3.1 用例设计3.2 实体设计 四、系统展示五、核心代码5.1 查询我的就业状况5.2 初始化就业状况5.…

2024.3.18-408学习笔记-C-结构体

1、结构体 结构体是一种自定义类型。 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 2、结构体的声明 struct Student {char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号 };//分号不能丢以上声明的结构…

单链表OJ题

单链表OJ题(文字解读 图解) 1. 移除链表元素2. 反转链表3. 链表的中间结点4. 返回倒数第 k 个节点5. 合并两个有序链表 1. 移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点&#xff…

第六节:使用SMB开发WebService

一、概述 webservice在日常开发中是常用的接口形式,SMB在设计之初就将webservice作为重要的代理协议。在组件库中提供了webservice input和webservice output两个组件,分别用于发布接口和调用接口。 二、发布webservice 在csdnProject工程中创建名为c…

【设计模式】-工厂模式

工厂模式是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的方法。工厂模式的核心思想是将对象的创建与使用分离,降低系统的耦合度,使系统更加灵活、可扩展。 工厂模式主要分为三种类型:简单工厂模式、工厂方法…

#Ubuntu(修改root信息)

(一)发行版:Ubuntu16.04.7 (二)记录: (1)命令行终端: a.右键,open terminal b.快捷键 ctrlaltt (2)进行root修改 sudo passwd &a…

【LeetCode周赛】第 389 场周赛

目录 3083. 字符串及其反转中是否存在同一子字符串 简单3084. 统计以给定字符开头和结尾的子字符串总数 中等3085. 成为 K 特殊字符串需要删除的最少字符数 中等3086. 拾起 K 个 1 需要的最少行动次数 困难 3083. 字符串及其反转中是否存在同一子字符串 简单 3083. 字符串及其…

程序员快速自我提升法——鱼皮大佬

0 软件开发人员自我成长 1 每天读2~3篇文章,可以行业趋势、技术类(和自己的工作有关的) 大厂技术博客科技资讯类:量子位、差评、新智元、无敌信息差 量子位、新智元经验分享、编程趋势、技术干活:程序员鱼皮、小林coding、java guide、程序…

【推荐系统】NCF神经协同过滤

NCF框架 NCF框架是本文要实现的3个模型的主体结构。 首先是输入层,分别包含两个特征向量 v u v_u vu​和 v i v_i vi​,描述了用户u和物品i。输入仅由一个用户向量和一个物品向量构成,它们分别是以one-hot编码的二值化稀疏向量。 接着是Em…

[HNCTF 2022 WEEK2]e@sy_flower

获取基本信息 获取关键字符串 进来“开门红” 上一篇博客才发现这个 按u转换为二进制 有个无效db,最简单的花指令 nop掉 重新u一下p一下 就正常了 然后编译完main函数 int __cdecl __noreturn main(int argc, const char **argv, const char **envp) {signed in…

机器学习算法大全(MLS-C01)

算法名字监督学习简介和用途协同过滤是推荐算法Factorization Machines algorithm否推荐算法,准确度更高,不会误打扰。KNN否利用已知样本,找最邻近的样本的分类算法K-means否聚类算法RCF否异常检测Latent Dirichlet Allocation否主题提取和文…

Python深度学习技术教程

原文链接:Python深度学习技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247597949&idx4&sn65c0d353d02b060fec98ec799f217ae1&chksmfa823e9acdf5b78cd71cfcb060e3b60125b17afbe3e19ef423d4709d2df7fc93d90ce3097253&token14787…

Unity InputField实现框自适应内容简便方法

要实现InputField框自适应输入内容,除了通过代码进行处理,还可以是使用以下简便的方法。 1、创建InputField组件:右键->UI->Input Field -TextMeshPro。 2、把Input Field Settings中的Line Type设置为Multi Line Newline模式&#x…

Jenkins + Docker + ASP.NET Core自动化部署

本来没想着要写这篇博客,但是在实操过程中,一个是被网络问题搞炸了心态(真心感觉网络能把人搞疯,别人下个包、下个镜像几秒钟搞定,我看着我的几KB小水管真是有苦说不出),另一个就是这里面坑还是…

5. 最长回文子串

5. 最长回文子串 中等 相关标签 相关企业 提示 给你一个字符串 s,找到 s 中最长的回文 子串 。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 示例 1: 输入:s "babad" 输出:&quo…

2024.2.28 校招 实习 内推 面经

绿*泡*泡VX: neituijunsir 交流*裙 ,内推/实习/校招汇总表格 1、校招 | OPPO流程IT团队 校招扩招 (内推) 校招 | OPPO流程IT团队 校招扩招 (内推) 2、校招 | 顺丰集团2024届春季校园招聘正式启动&#…

【Java】高级篇1:异常处理

异常:程序在执行过程中出现的非正常情况,如果不处理最终会导致JVM的非正常停止。 Java的异常抛出机制 Java异常体系 1、Throwable 2、Error和Exception 异常处理方式 1、try-catch-finally(捕获异常) 基本结构: 使用…

算法笔记p328_并查集

目录 并查集的定义并查集的基本操作初始化查找合并 路径压缩 并查集的定义 并查集是一种维护集合的数据结构,支持下面两个操作: 合并:合并两个集合。查找:判断两个元素是否在一个集合。 并查集用一个数组实现: int…

OpenJudge - 12:计算2的N次方

总时间限制: 1000ms 内存限制: 65536kB 描述 任意给定一个正整数N(N<100)&#xff0c;计算2的n次方的值。 输入 输入一个正整数N。 输出 输出2的N次方的值。 样例输入 5 样例输出 32 关键代码 #include<stdio.h> int main() {int n,a[51] {0},c[51] {0},count 0…

Day68:WEB攻防-Java安全原生反序列化SpringBoot攻防heapdump提取CVE

目录 Java安全-反序列化-原生序列化类函数 原生序列化类函数 SnakeYaml XMLDecoder ObjectInputStream.readObject 工具利用 ysoserial Yakit SerializedPayloadGenerator Java安全-SpringBoot框架-泄漏&CVE SpringBoot Actuator-黑白盒发现 人工识别 BurpSui…