追逐本源,放弃浮华
EarthWorm

Termite

Friends

RSS

Python元类(小李很悲剧)

25 Feb 2017 TAGS : [ 技术相关 Python编程 metaclass 元编程 元类 ]

Python元类

最近一直在写Python代码,但是每创建一个类,都要重新写一套set和get方法,麻烦的要死,而且每加一个新成员都要配套一堆相关方法,真的很浪费时间,如果能把这些时间统统节省下来,那必是极好的。

在Python中有“元类”的概念,其作用就是动态创建一个类,包括其成员以及相应方法。基于元类,可以快速生成一个新类,并自动生成一些常用的工具方法,以节省时间。

下面就用小李的悲剧,来看一下这个类的使用情况。

小李的悲剧

小李的初始化

大概用了一天时间写了一个工具类ClassBuilder,有了这个类,我们可以很快速的定义一个学生类来描述小李同学。他是个学生,今年20岁了:

由于Student继承了ClassBuilder这个类,那么ClassBuilder就会为类中的Name和Age两个成员自动创建出相应的set方法和get方法,所以在 main 函数中就可以直接使用set_Name,set_Age,get_Name,get_Age四个方法了,以上代码的运行效果如下:

值得注意的是由于ClassBuilder自动创建了__str__ 方法,所以在主函数的 22 行才可以直接将小李的所有信息print出来。

小李出名了(值传递)

小李因为一些不可告人的原因,竟然出名了,想知道他详细信息的人多如牛毛,为了方便他人认识小李,我们需要将小李的详细信息以某种方式打包起来,再以某种方式还原出来,在ClassBuilder的帮助下,可以通过json数据格式完成这一过程。

任何类继承了ClassBuilder后还会自动生成buildJSON和loadJSON两个方法,以便快速的将一个类的值转化成json数据,或从json反向恢复一个类。样例代码如下:

在代码的22 行,使用 tt 对象的 buildJSON 方法将类中所有数值转存为 json 字符串,而第28 行则用loadJSON方法从这个json字符串还原一个 t2 对象,29-30两行代码则是验证还原结果。上述代码的执行效果如下图所示:

虽然目前还不知道小李出名的具体原因,但我们已经可以通过buildJSON和loadJSON两个方法分发小李的详细个人信息了,要注意我们并没有为Student类添加任何与之相关的代码,想想还真有些小激动呢。

列表成员

每一个正常的学生,应该都有数量不等的标签,小李作为一个正常的学生,也要适应这一情况,学生类中需要一个新的列表成员来描述这一变化。如下所示:

从23-24行不难看出,小李不光是个学霸,而且还是个帅哥,很有前途,其实代码的执行结果也印证了这一点:

字典成员(小李的成绩)

当学生免不了要考试,小李作为资深学霸,自然应该门门功课都满分。又要给学生类加新成员了。

小李果然是个“真·学霸”,仅有的两门功课都打了120分,但我很好奇,明明满分是100分,他怎么会多打20分,真是见鬼了,小李还真是个谜一样的人。

移除列表成员(东窗事发)

他的老师也同样对小李的成绩有些疑问,调查后发现,这小子真不是个省油的灯,他竟然敢伪造老师的笔记给自己卷子打分,要不是这次给自己多打了20分,可能大家还会继续把他当学霸。既然他不是个学霸,那自然应该把学霸的标签移除。

小李的真实面目被曝光后,我们还要好好对比下出事前后小李个人信息的更新情况。

尾记

小李的故事讲完了,相信一定有人知道他出名的真实原因了。

不知道是否有人注意到,在讲整个故事的过程中,我们并没有对Student类做过多的修改,甚至没有定义任何新的函数。其实这全都是ClassBuilder这个类的功劳。

ClassBuilder这个类是从Python元类出发编写的,对其魔力感兴趣的小伙伴可以到这里下载并阅读。

虽然在本文中ClassBuilder被用来讲述小李的传奇故事,但ClassBuilder中内置的几个方法却会在工程中却经常用到,这个类未来一定会成为一个伟大的类,并出现在我的各种项目代码中。

TAGS : [ 技术相关 Python编程 metaclass 元编程 元类 ]