Python学习笔记29:继承的优缺点

本文探讨Python继承的优缺点,包括内建类的继承缺陷和多重继承的菱形问题及其解决方案MRO。讲解了如何通过MRO解决同名方法冲突,并提出了在多继承中应遵循的原则,如使用混入、明确继承主体和多用组合。
摘要由CSDN通过智能技术生成

Python学习笔记29:继承的优缺点

  • 最近因为一些别的事所以没有继续学习和更新,抱歉了。今天回到学习Python的道路上,我们继续旅途。
  • 本系列今后的示例代码都将存放在Github项目:https://github.com/icexmoon/python-learning-notes

从最近的几篇笔记开始,我们开始探索Python中的OOP。

前一篇笔记Python学习笔记28:从协议到抽象基类我们从协议和抽象类两个方面探讨了协议和抽象类在Python中的定位和用途。

今天我们要讨论的是Python中继承的特点,和其中的优缺点。

内建类的继承缺陷

这是一个隐蔽的问题和缺陷,至少在Java或者PHP中我并没有发现类似的问题。

至于我说的是什么,不要着急,我们往下看。

我们创建一个字典类型的子类,并重写__setitem__魔术方法:

class SubDict(dict):
    def __setitem__(self, k, v):
        v = "sub_item_"+str(v)
        super().__setitem__(k, v)

sd = SubDict(one="one")
print(sd)
sd['two']='two'
print(sd)
sd.update(three="three")
print(sd)
# {'one': 'one'}
# {'one': 'one', 'two': 'sub_item_two'}
# {'one': 'one', 'two': 'sub_item_two', 'three': 'three'}

我们分别通过初始化方法、直接对元素赋值、调用update方法进行测试。

其中只有直接对元素赋值成功调用了我们重写的__setitem__,实质上__setitem__魔术方法本来就是对字典元素赋值操作的运算符重载,所以这是个必然结果。

而我们需要关注的是其它两种方式为何没有成功。

有一个事实我们是需要知道的,就是虽然Python的最大特点是让普通的开发者拥有和语言底层开发者一样的语言特性,但是实质上为了优化性能,并非所有的内建组件都用一致性的Python语言开发,比如最常用的组件:字典、列表和字符串,都是使用效率更高的C语言进行编译的可执行模块(对CPython解释器来说)。

这样做的好处显而易见,可以极大地提升性能,并且对普通开发者基本是没有任何影响的,但是在极个别情况下就会发生一些奇怪的现象,比如我们上面展示的那样。

如果你对这些C语言构建的内部组件进行继承并重写某些方法,很可能在调用的时候其行为并不会符合OOP中多态的行为。即父类并不会使用你重写的方法(比如__setitem__),这就是我所说的内建类的继承缺陷。

当然Python官方也给出了解决办法,在需要对此类内建类进行继承的时候,我们不应该直接继承,而是应该继承collections模块中的UserXXX类,这些类是纯Python编写,不存在以上所说的问题。

我们用这种方式改写刚才的示例:

from collections import UserDict
class SubDict(UserDict):
    def __setitem__(self, k, v):
        v = "sub_item_"+str(v)
        super().__setitem__(k
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值