一、核心要义
1. 子类化内置类型的缺点
2.多重继承和方法解析顺序
二、代码示例
1. 子类化内置类型的缺点
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/2/24 7:29
# @Author : Maple
# @File : 01-子类化内置类型的问题.py
# @Software: PyCharm
from collections import UserDictclass DroppedDict(dict):# 继承内置类型dict:底层用C语言实现的def __setitem__(self, key, value):super().__setitem__(key,[value]*2)class DroppedDict2(UserDict):# 继承Python编写的类:UserDictdef __setitem__(self, key, value):super().__setitem__(key, [value] * 2)if __name__ == '__main__':# 1. DroppedDict测试## 1-1 初始化dd = DroppedDict(one = 1)print(dd)## 1-2 添加元素:会正常调用自定义的__setitem__方法dd['two'] = 2print(dd) # {'one': 1, 'two': [2, 2]},传入的value 2复制了一份:[2]*2 -->[2,2]## 1-3 更新字典:并不会调用我们自定义的__setitem__方法## 本来更新的时候,因为key = three并不存在于dd,所以应该要通过__setitem__给dd新增key-value值,但实际并不会调用我们自定义的方法dd.update(three = 3)print(dd) # {'one': 1, 'two': [2, 2], 'three': 3} -->第三个元素并不是'three':[3,3]# 2. DroppedDict2测试## 2-1 初始化dd2 = DroppedDict2(one=1)print(dd2) # {'one': [1, 1]}## 2-2 添加元素:会正常调用自定义的__setitem__方法dd2['two'] = 2print(dd2) # {'one': 1, 'two': [2, 2]},传入的value 2复制了一份:[2]*2 -->[2,2]## 2-3 更新字典:会正常调用我们自定义的__setitem__方法dd2.update(three=3)print(dd2) # {'one': [1, 1], 'two': [2, 2], 'three': [3, 3]}
2. 多重继承和方法解析顺序
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2024/2/24 7:41
# @Author : Maple
# @File : 02-多重继承和方法解析顺序.py
# @Software: PyCharmclass A:def ping(self):print('ping',self)class B(A):def pong(self):print('pong',self)class C(A):def pong(self):print('PONG',self)class D(B,C):def ping(self):super().ping()print('post-ping',self)def pingpong(self):self.ping()super().ping()self.pong()super().pong()C.pong(self)if __name__ == '__main__':# 1. 类D的继承关系# D -> B -> C -> A -> objprint(D.__mro__) # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)# 2. 继承输出测试1d = D()# 1.子类并没有pong,所以会调用父类的pong# 2.同时根据父类继承顺序,会调用父类B的的pong方法d.pong() # pong <__main__.D object at 0x0000019244D4A730>print('***************************')# 3. 继承输出测试2"""ping <__main__.D object at 0x0000025A7776A730>post-ping <__main__.D object at 0x0000025A7776A730>ping <__main__.D object at 0x0000025A7776A730>pong <__main__.D object at 0x0000025A7776A730>pong <__main__.D object at 0x0000025A7776A730>PONG <__main__.D object at 0x0000025A7776A730>"""# 1. 调用self.ping()--> super().ping()和print('post-ping',self),其中前者会调用A类的ping方法;后者则打印,无需多言# 2. 调用 super().ping()-->调用A类的ping方法# 3. 调用self.pong(),由于D类本身没有pong方法,因此会调用父类的pong方法,同时根据父类继承优先级,是去调用B类的pong方法# 4. 调用super().pong()-->B类的pong方法# 5. C.pong(self) -->调用C类的pong方法d.pingpong()