Python自动生成代码工具
项目中有一个需求,对一个基类而言,拥有一个比较方法和拷贝方法,某些地方需要频繁地对这两个方法进行调用。对于所有子类而言,需要重写这两个方法,并在其中维护类内一些成员变量。例如有一个变量m_iMyVal,在Copy方法中需要维护this.m_iMyVal = data.m_iMyVal;在IsEqual方法中需要维护if(this.m_iMyVal != data.m_iMyVal) return false;...等等。当子类中的变量一旦多了,譬如一个类中拥有十余个甚至更多这样的变量,并且日后有可能删除或添加,维护起来就有点痛苦了,因为需要在两处都补充对应的方法,而且每一个都不能写漏写错。
这些子类一般都是数据类,在编写代码的时候往往是一口气写相当多的变量,如果写一个然后到两个地方编写对应的代码,这样可能的确出错率比较低,但是很容易打断思路;但是把所有变量写完后再去补充代码,就会有写漏写错之嫌,一旦写漏当时可能没有bug,后期查错起来非常痛苦,从而导致开发效率下降。另外麻烦的一点在于,不同类型的变量,比较方法和拷贝方法可能不尽相同(如浮点数需要eps,list需要循环比较等等)。
那么有没有写一个变量然后告诉系统这个变量是需要在比较和拷贝方法中补充代码的,然后有“人”帮我自动补充上去呢?由于笔者使用的是C#语言开发,自然而然想到了添加标签的方法,之后通过反射找到所有带有这种标签的成员变量,在比较和拷贝方法中直接进行操作即可。
但是担心这种做法由于反射有性能较低之嫌,因此暂时不作考虑,转而使用下面这种利用Python自动生成代码的方法。
利用Python读取文件,正则查询带有某些标签或者注释的变量,把这些变量收集起来,然后替换原文件的比较和拷贝方法即可。
那么工作流就变成了:
1.写需要的成员变量
2.如果需要自动为其生成代码,则添加对应的标签(不采用注释的方法是因为标签可以被自动补全,防止正则找错)。
3.执行批处理文件,自动把需要的文件生成代码(如果之前有这部分代码,则是替换)。
整个过程几乎不耽误什么时间,但是自动生成代码使得开发效率大大提升。
Python源码如下:
# -*- encoding:utf-8 -*- import os
import sys
import re def process_file(path):
keyword = 'debug_util.'
modify_flag = False auto_start = "// python automatic generation start"
auto_end = "// python automatic generation end"
normalLabel = "\[NormalLabel\]"
floatLabel = "\[FloatLabel\]"
vec3Lable = "\[Vec3Label\]" normalCmp = "[NormalLabel]"
floatCmp = "[FloatLabel]"
vec3Cmp = "[Vec3Label]" with open(path, 'rb') as f:
txt = f.read()
# print ("txt is " + txt)
pattern = "(%s|%s|%s)[\s\S]+?public\s+\w+\s+(\w+)" % (normalLabel, floatLabel, vec3Lable)
matchStr = re.findall(pattern, txt)
# print (matchStr)
labelList = []
varList = []
for i, packed in enumerate(matchStr):
labelName = packed[0]
varName = packed[1]
labelList.append(labelName)
varList.append(varName)
# print (labelName + ".." + varName) # 开始找类的名称
pattern = "public class (\w+)\s*:\s*SkillBaseData"
matchStr = re.findall(pattern, txt)
className = ""
for i, packed in enumerate(matchStr):
className = packed
break # 类名只会有一个 ## 找注释部分
index = 0
begin = txt.find(auto_start, index) + len(auto_start)
end = txt.find(auto_end, index)
copyContent = ""
equalContent = ""
for labelName, varName in zip(labelList, varList):
copyContent += "\t\t\tthis." + varName + " = data." + varName + ";\n"
if labelName == normalCmp:
equalContent += ("\t\t\tif(this.%s != data.%s) return 1;\n" % (varName, varName))
elif labelName == floatCmp:
equalContent += ("\t\t\tif(FloatNotEqual(this.%s, data.%s)) return 1;\n" % (varName, varName))
elif labelName == vec3Cmp:
equalContent += ("\t\t\tif(Vec3NotEqual(this.%s, data.%s)) return 1;\n" % (varName, varName)) auto_code = ""
auto_code += (("\n\t\tpublic override void CopyDataFrom(SkillBaseData baseData)\n\t\t{\n\t\t\tvar data = (%s)baseData;\n" % className) + copyContent + "\t\t}\n")
auto_code += (("\n\t\tpublic override int IsEqual(SkillBaseData baseData)\n\t\t{\n\t\t\tvar data = (%s)baseData;\n" % className) + equalContent + "\t\t\treturn 0;\n\t\t}\n")
print (txt[:begin] + auto_code + txt[end:])
new_txt = txt[:begin] + auto_code + "\t\t" + txt[end:]
with open(path, 'wb') as f:
f.write(new_txt) def okPath(path):
if path.endswith("TestSkillData.cs"):
return True return False if __name__ == '__main__':
cwd = os.getcwd()
_len = len(cwd) - 22 # 22是最后一级目录的长度,在这里是魔法数字,据需求而改动,当然也可以用其他方法找到需要的目录= =。
cwd = cwd[:_len] + 'SkillDerivedData'
print(cwd)
# cwd = cwd + '/Package/Script/Python/'
directiory = os.walk(cwd)
for root, dirs, files in directiory:
for f in files:
if okPath(f):
process_file(os.path.join(root, f))
# print("name is " + f)
Python自动生成代码工具
写完C#直接跑下面这个bat即可。

最后生成代码的效果如下图所示,感觉还算比较美观的= =。(针对三种不同的标签提供了不同的处理方法):

总的来说,学会了一种新的处理问题的方法,收获挺大的。最后感谢一下教会我这种方法的@仓鼠和提供正则帮助的@聪哥。
Python自动生成代码工具的更多相关文章
- mybatis自动生成代码工具(逆向工程)
MyBatis自动生成实体类(逆向工程) MyBatis属于一种半自动的ORM框架,它需要我们自己编写sql语句和映射文件,但是编写映射文件和sql语句很容易出错,所以mybatis官方提供了Gene ...
- swagger-codegen自动生成代码工具的介绍与使用
一.Swagger Codegen简介 Swagger Codegen是一个开源的代码生成器,根据Swagger定义的RESTful API可以自动建立服务端和客户端的连接.Swagger Codeg ...
- SpringBoot与Mybatis整合(包含generate自动生成代码工具,数据库表一对一,一对多,关联关系中间表的查询)
链接:https://blog.csdn.net/YonJarLuo/article/details/81187239 自动生成工具只是生成很单纯的表,复杂的一对多,多对多的情况则是在建表的时候就建立 ...
- mybatis-generator自动生成代码工具
1.在项目的配置文件中放入配置文件mybatis-generator-config.xml 根据情况修改下配置 <?xml version="1.0" encoding= ...
- Mybatis自动生成代码工具
项目结构如下 一:在POM中添加mybatis-generator-maven-plugin 插件 <plugins> <plugin> <groupId>org. ...
- Swagger Edit自动生成代码工具
一.swagger简介 swagger是一套开源的API设计工具,包括Swagger UI和Swagger Editor等.其中swagger edit是用来编辑接口文档的小程序,非常简单易用.在官网 ...
- 自动生成代码工具【JAVA版】
发现任何项目无非五类操作:新增.修改.删除.查询详细.查询列表 大多数的服务端基础代码都是相同的,但是每次开发一个新项目都会做很多重复工作,从controller,bean,service,到数据库访 ...
- mybatis 自动生成代码工具
配置官网: http://www.mybatis.org/generator/configreference/xmlconfig.html 源码:https://github.com/mybatis/ ...
- (Python)自动生成代码(方法一)
在写某个平台的自动化脚本时,笔者把全部的操作都封装到了两个类中,page.py和commonpage.py: page.py部分代码: class BasePage(object): ''' 页面基础 ...
随机推荐
- Java Web 深入分析(11) JVM(1)
前言 Java启动后作为一个进程运行在操作系统中,该进程要分配的内存有以下几个: 1.Java堆: 存储java内存区域,堆大小是在jvm启动时就像操作系统申请完成,其中 -Xmx和-Xms 分别表示 ...
- 如何回答——请简述MySQL索引类型
想必大家在被问到这个问题的时候,在网上总是能搜到不同的回答,却又各不相同.其实这些答案大部分都是正确的,只不过在阐述MySQL索引类型的时候从不同方面入手而已.这里归纳如下,具体的机制可以参考其他博文 ...
- python day 9: xlm模块,configparser模块,shutil模块,subprocess模块,logging模块,迭代器与生成器,反射
目录 python day 9 1. xml模块 1.1 初识xml 1.2 遍历xml文档的指定节点 1.3 通过python手工创建xml文档 1.4 创建节点的两种方式 1.5 总结 2. co ...
- 关于ES6的对象扩展运算符
对象的扩展运算符(...),用于取出参数对象中的所有可遍历属性,然后拷贝到当前对象之中 对象扩展运算符: 1. 复制对象 let obj1 = { x: 1, y: 2, z: 3 } let obj ...
- Java新功能之方法引用
方法引用的使用 最初,引用只是针对引用类型完成的,也就是只有数组.类.接口才具备引用操作.JDK1.8后追加了方法引用.实际上引用的本质就是别名. 因此方法的引用就是别名的使用. 方法的引用有四种形式 ...
- VIM的配置以及插件管理
VIM的配置详细说明参考:http://www.ruanyifeng.com/blog/2018/09/vimrc.html 此外VIM的插件管理比如 Vundle可以参考这个博客: https:// ...
- 用c#监控网络流量
using System; using System.Text; using System.Net; using System.Net.Sockets; using System.Runtime.In ...
- C语言基础知识-数据类型
C语言基础知识-数据类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.常量与变量 1>.关键字 C的关键字共有32个. >.数据类型关键字(12个) char,s ...
- Ansible_Day1
1.传统运维&自动化运维概念 1)传统的运维概念(硬件.软件.系统.网络) 手工安装系统.机房建设: 软件服务配置.部署通过手工的操作: 没有自动化脚本.流程: 依靠大量的运维人员完成任务: ...
- Windows运维之Windows8.1-KB2999226-x64安装提示 此更新不适用你的计算机
摘要:本文主要向大家介绍了Windows运维之Windows8.1-KB2999226-x64安装提示 此更新不适用你的计算机,通过具体的内容向大家展现,希望对大家学习Windows运维有所帮助. 本 ...