应用Python写的一个简单的Class代码生成器

平时苦于写一下C++类或数据结构时时,每个类都需要四五个与类相关的构造、析构函数。每次重复的写些类名和变量名,费时费力。若将这些函数省略,代码风格不好,又不安全。

经常见一些代码生成工具,只需定义类名,变量,函数,就能生成比较完善的代码。格式统一,漂亮且安全。不过这些工具都与自己的框架或编译系统相关,通用性不是很好。

最近想学习下python的应用,就尝试自己写一个简单的Class代码生成器。按照一般的思路:设计漂亮易用的界面,生成类型定义的xml或其他格式的数据文件,然后再翻译成代码。这个工作量和设计复杂程序对我这个python新手短时间内是不可能的。按照2/8原则,设计一个最简单易用的界面,尽可能的完成一些重复性的劳动。


期望的 工具使用方式:

只需在一个文本文件,如declare.txt中,第一行写入类名,然后以下每行写入 类型名和变量名即可。

生成的代码,包括类的声明和各种构造和析构函数。


如:declare.txt文件中

Test  
int a
float b
string c

需要生成的目标代码:

class Test
{
    Test();
    Test(int _a, float _b, const string &_c);
    Test(const Test &rhs);
    Test& operator = (const Test &rhs);
    ~Test();

public: // private:
    int a; 
    float b; 
    string c;
};


Test::Test()
: a()
, b()
, c()
{
}

Test::Test(int _a, float _b, const string &_c)
: a(_a)
, b(_b)
, c(_c)
{
}

Test::Test(const Test &rhs)
{
	*this = rhs;
}

Test& Test::operator = (const Test &rhs)
{
	if (&rhs != this)
	{
        	a = rhs.a; 
        	b = rhs.b; 
        	c = rhs.c;
	}

	return *this;
}

Test::~Test()
{
}

设计思路:
输入方式确定,输出结果的格式也确定。首先,将结果中不变的东西提取出来,如类的格式,制成模板:

class ClassName
{
    ClassName();
    ClassName(ConstructorParameterList);
    ClassName(const ClassName &rhs);
    ClassName& operator = (const ClassName &rhs);
    ~ClassName();

public: // private:
    VariableList
};


ClassName::ClassName()
: DefaultInitializationList
{
}

ClassName::ClassName(ConstructorParameterList)
: ParameterInitializationList
{
}

ClassName::ClassName(const ClassName &rhs)
{
	*this = rhs;
}

ClassName& ClassName::operator = (const ClassName &rhs)
{
	if (&rhs != this)
	{
        AssignmentList
	}

	return *this;
}

ClassName::~ClassName()
{
}

然后,只需要将ClassName替换为定义的类名,将定义的变量组合成 变量声明列表、构造函数参数列表、赋值函数列表,替换掉VariableList,DefaultInitializationList,ConstructorParameterList, ParameterInitializationList, AssignmentList。


Python代码只需完成一些 字符串的组合,替换等。

import sys                       # Load the sys module (导入sys模块)
import string

def ReplaceStrings(stringlist, fromString, toString):
    for i in range(0, len(stringlist)):
        s = stringlist[i]
        s = string.replace(s, fromString, toString); 
        stringlist[i] = s
        #print stringlist[i]

f = open("template.txt")            # template.txt
templateTextLines = f.readlines()          # Read all lines into a list (读出所有行到一个列表)
f.close()

f = open('declare.txt')#(sys.argv[1])            # Filename on the command line (从命令行读取文件名)
declareLines = f.readlines()          # Read all lines into a list (读出所有行到一个列表), strip all space and \n
f.close()

typeString = ""
nameString = ""

variableListstring = ""
constructorParameterListString = ""

defaultInitialListString = ""
parameterListString = ""
assignmentListString = ""

for i in range(1, len(declareLines)):
    lineString = declareLines[i]
    lineString = lineString.lstrip()
    lineString = lineString.rstrip()
    lineString = lineString.rstrip("\n")
    if lineString == "":  # 跳过空行
        continue
    splittedStrings = lineString.split()
    if len(splittedStrings) > 1:  #假定类型和变量名是两个字符串,后续修改:因为有的类型不止一个字符串如unsigned int
        typeString = splittedStrings[0]
        nameString = splittedStrings[1]

    variableListstring += lineString + "; \n    "
    if typeString=="int" or typeString=="float" or typeString=="double" or typeString=="UInt32" or typeString=="Int32" or typeString == "Float32": # 可自行增加
        constructorParameterListString += typeString + " _" + nameString + ", " #基本类型,采用传值的方式
    else:
        constructorParameterListString += "const " + typeString + " &_" + nameString + ", " #自定义类型,采用传引用方式

    defaultInitialListString += nameString + "()\n, "
    parameterListString += nameString + "(_" + nameString + ")\n, "
    assignmentListString += nameString + " = rhs." + nameString + "; \n        "

variableListstring = variableListstring.rstrip(" \n    ")   # 去掉多余的尾部符号
constructorParameterListString = constructorParameterListString.rstrip(", ")
        
defaultInitialListString = defaultInitialListString.rstrip("\n, ")
parameterListString = parameterListString.rstrip("\n, ")
assignmentListString = assignmentListString.rstrip(" \n        ")

ReplaceStrings(templateTextLines, "ClassName", declareLines[0].strip("\n").strip())

ReplaceStrings(templateTextLines, "VariableList", variableListstring)
ReplaceStrings(templateTextLines, "DefaultInitializationList", defaultInitialListString)
ReplaceStrings(templateTextLines, "ConstructorParameterList", constructorParameterListString)
ReplaceStrings(templateTextLines, "ParameterInitializationList", parameterListString)
ReplaceStrings(templateTextLines, "AssignmentList", assignmentListString)

f = open("out.txt","w")     # Open file for writing
for s in templateTextLines:
    f.write(s)
#    print s
f.close()

边学边写,弄了一天,功能不完善,不能添加函数,变量类型声明目前只能是一个字符串,代码没什么风格和结构。不过,简单易用,后面的功能可以慢慢添加。
另外,学习了python的基本语法
python在使用上与c++明显的不同:
1. 用:及缩进 代替{}
2. 无需定义变量的类型
3. 没有&&, ||,!而是and,or,not
4. 关键字都是小写
5. 作为函数参数时,string,tuples, 和numbers等基本类型,是传值的方法,函数内更改无效;而元组、列表的内容是可以更改的,类似于传指针或引用的方式。
参考:http://blog.csdn.net/winterttr/article/details/2590741
6. string函数,不更改自身,更是返回执行或修改的结果,若更改自身,需要接收结果,如
variableListstring = variableListstring.rstrip(" \n    ")   # 去掉多余的尾部符号
7. 后续


学习python的网站: http://wiki.woodpecker.org.cn/moin/WeiZhong/2006-01-17

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值