35、Python之面向对象:基于抽象类半成品,高效实现自定义序列类

南宫理的日志录 2024-10-15 10:44:57
引言

上一篇文章中,我们简单介绍了抽象基类ABC,也很简略地介绍了其使用场景,但是,估计不少同学还会觉得没什么卵用,反而是费力不讨好……

今天这篇文章中,我打算通过实现自定义序列类的实例,来展示到抽象基类的作用,进一步加深对抽象基类的理解。

业务场景

基于前面的打工人的实例,我们继续扩展,假设我们有若干个打工人组成了一个团队,然后写了如下代码:

执行结果:

看着似乎没啥问题,但是,我们能不能像是用list一样使用Team类的实例对象呢,比如,我们可以进行for循环遍历一个Team实例对象,可以对其进行[]索引的操作。

方法1:通过继承list实现

其实实现方法可以有很多种,比如最容易想到的直接继承自list类。

直接看代码:

执行结果:

通过直接继承list方法,其实很简洁,我们只需要定义类的时候声明继承list,然后通过super的方式调用list的初始化。

然后,看到的效果就是Team类的实例对象,已经支持了list的各种适应场景,比如可以[]索引、比如可以使用len()统计个数,可以放到for循环中。同时list本身的方法也都是可以使用的,比如:append()、pop()等,可以自行尝试。

方法2:继承自抽象基类

继承自list的方法很简洁,但是,因为是一种偷懒的方式,掩盖了实现的一些细节,而这些细节涉及到Python中特定语法解析的对象协议。

接下来,我们通过继承抽象基类:collections.MutableSequence的方法来实现需求,然后再简单解释相关的对象协议。

还是直接看代码:

执行结果:

从执行结果看,虽然没有继承list,但是,我们依然实现了前一种方法的各种使用场景。

这种实现方式中,我们通过继承MutableSequence这个抽象基类,然后实现了其中的几个抽象方法,大部分都是__打头的方法名。

简单说明一下这些方法:

1、insert()方法:当我们调用append()方法时,实际上会调用insert()方法的实现。

2、__getitem__()方法:当我们对对象进行[]索引,或者进行for循环遍历时,会自动调用对象中的__getitem__()方法。

3、__setitem__()方法:修改某个元素时,会自动调用该方法。

4、__delitem__()方法:通过del删除某个元素时,会调用该方法。

5、__len__()方法:当通过使用内置函数len()计算元素个数时,会自动调用该方法。

总结

这篇文章中,我们通过两种方式,实现了自定义序列类的效果,使得自定义类的实例对象也支持内置对象的类似的行为。

需要说明的是,这些__xxx__的方法,在Python中被称为“魔术方法”,可以理解为要想对象支持某种行为,需要遵守的协议。

感兴趣的同学,可以试一下,即使不显式继承任何类,只需要在类中实现特定的魔术方法,也能实现[]索引、for循环遍历等效果。

关于魔术方法的内容,在后续的文章中,将会进行系统的介绍。

感谢您的拨冗阅读,如果对您学习Python有些许帮助,欢迎点赞、收藏。

0 阅读:3

南宫理的日志录

简介:深耕IT科技,探索技术与人文的交集