first commit

This commit is contained in:
2025-08-27 14:39:37 +08:00
commit 81ebee9cf3
97 changed files with 14191 additions and 0 deletions

View File

@@ -0,0 +1,422 @@
# 类的继承
## 面向对象的继承
不用继承创建对象
```python
class Person:
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
class Cat:
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
class Dog:
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
```
使用继承的方式
```python
class Aniaml(object):
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
class Person(Aniaml):
pass
class Cat(Aniaml):
pass
class Dog(Aniaml):
pass
```
继承的有点也是显而易见的:
1. 增加了类的耦合性(耦合性不宜多,宜精)。
2. 减少了重复代码。
3. 使得代码更加规范化,合理化。
## 继承的分类
上面的那个例子:
- Aminal 叫做父类,基类,超类。
- Person Cat Dog: 子类,派生类。
继承:可以分**单继承,多继承**。
这里需要补充一下python中类的种类继承需要
在python2x版本中存在两种类.
- ⼀个叫**经典类**. 在python2.2之前. ⼀直使⽤的是经典类. 经典类在基类的根如果什么都不写.
- ⼀个叫**新式类**. 在python2.2之后出现了新式类. 新式类的特点是基类的根是object类。
python3x版本中只有一种类
python3中使⽤的都是**新式类**. 如果基类谁都不继承. 那这个类会默认继承 object
## 单继承
### 类名,对象执行父类方法
```python
class Aniaml(object):
type_name = '动物类'
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print('吃',self)
class Person(Aniaml):
pass
class Cat(Aniaml):
pass
class Dog(Aniaml):
pass
print(Person.type_name)
Person.eat('东西')
print(Person.type_name)
p1 = Person('aaron','男',18)
print(p1.__dict__)
print(p1.type_name)
p1.type_name = '666'
print(p1)
p1.eat()
```
### 执行顺序
```python
class Aniaml(object):
type_name = '动物类'
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print('吃',self)
class Person(Aniaml):
def eat(self):
print('%s 用筷子吃饭'%self.name)
class Cat(Aniaml):
pass
class Dog(Aniaml):
pass
p1 = Person('eagle','男',18)
p1.eat()
```
### 同时执行类以及父类方法
方法一如果想执行父类的func方法这个方法并且子类中夜用那么就在子类的方法中写上父类.func(对象,其他参数)
```python
class Aniaml(object):
type_name = '动物类'
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print('吃东西')
class Person(Aniaml):
def __init__(self,name,sex,age,mind):
Aniaml.__init__(self,name,sex,age)
self.mind = mind
def eat(self):
Aniaml.eat(111)
print('%s 吃饭'%self.name)
class Cat(Aniaml):
pass
class Dog(Aniaml):
pass
p1 = Person('aaron','男',18,'想吃东西')
p1.eat()
```
方法二利用supersuper().func(参数)
```python
class Aniaml(object):
type_name = '动物类'
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print('吃东西')
class Person(Aniaml):
def __init__(self,name,sex,age,mind):
# super(Person,self).__init__(name,sex,age)
super().__init__(name,sex,age)
self.mind = mind
def eat(self):
super().eat()
print('%s 吃饭'%self.name)
class Cat(Aniaml):
pass
class Dog(Aniaml):
pass
p1 = Person('aaron','男',18,'想吃东西')
p1.eat()
```
单继承练习题
```python
class Base:
def __init__(self,num):
self.num = num
def func1(self):
print(self.num)
class Foo(Base):
pass
obj = Foo(123)
obj.func1()
# 运⾏的是Base中的func1
```
```python
class Base:
def __init__(self,num):
self.num = num
def func1(self):
print(self.num)
class Foo(Base):
def func1(self):
print("Foo.func1",self.num)
obj = Foo(123)
obj.func1()
# 运⾏的是Foo中的func1
```
```python
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
self.func2()
def func2(self):
print("Base.func2")
class Foo(Base):
def func2(self):
print("Foo.func2")
obj = Foo(123)
obj.func1()
# func1是Base中的 func2是⼦类中的
```
```python
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
self.func2()
def func2(self):
print(111, self.num)
class Foo(Base):
def func2(self):
print(222, self.num)
lst = [Base(1), Base(2), Foo(3)]
for obj in lst:
obj.func2()
```
```python
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
self.func2()
def func2(self):
print(111, self.num)
class Foo(Base):
def func2(self):
print(222, self.num)
lst = [Base(1), Base(2), Foo(3)]
for obj in lst:
obj.func1()
```
## 多继承
```python
class ShenXian: # 神仙
def fei(self):
print("神仙都会⻜")
class Monkey: # 猴
def chitao(self):
print("猴⼦喜欢吃桃⼦")
class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是⼀只猴
pass
sxz = SunWukong() # 孙悟空
sxz.chitao() # 会吃桃⼦
sxz.fei() # 会⻜
```
### 经典类的多继承
```python
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
class E:
pass
class F(D, E):
pass
class G(F, D):
pass
class H:
pass
class Foo(H, G):
pass
```
画图
![image-20210725220109579](03.%E7%B1%BB%E7%9A%84%E7%BB%A7%E6%89%BF/image-20210725220109579.png)
在经典类中采⽤的是深度优先,遍历⽅案. 什么是深度优先. 就是⼀条路走到头. 然后再回来. 继续找下⼀个.
类的MRO(method resolution order): Foo-> H -> G -> F -> E -> D -> B -> A -> C.
### 新式类的多继承
#### mro序列
MRO是一个有序列表L在类被创建时就计算出来。
通用计算公式为:
mro(Child(Base1Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )其中Child继承自Base1, Base2
如果继承至一个基类class B(A)
这时B的mro序列为
mro( B ) = mro( B(A) )
= [B] + merge( mro(A) + [A] )
= [B] + merge( [A] + [A] )
= [B,A]
如果继承至多个基类class B(A1, A2, A3 …)
这时B的mro序列
mro(B) = mro( B(A1, A2, A3 …) )
= [B] + merge( mro(A1), mro(A2), mro(A3) ..., [A1, A2, A3] )
= ...
计算结果为列表,列表中至少有一个元素即类自己,如上述示例[A1,A2,A3]。merge操作是C3算法的核心。
#### 表头和表尾
表头:列表的第一个元素
表尾:列表中表头以外的元素集合(可以为空)
示例:列表:[A, B, C] 表头是A表尾是B和C
#### 列表之间的+操作
[A] + [B] = [A, B]
merge操作示例
如计算merge( [E,O], [C,E,F,O], [C] )
有三个列表 ① ② ③
1 merge不为空取出第一个列表列表①的表头E进行判断
各个列表的表尾分别是[O], [E,F,O]E在这些表尾的集合中因而跳过当前当前列表
2 取出列表②的表头C进行判断
C不在各个列表的集合中因而将C拿出到merge外并从所有表头删除
merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
3 进行下一次新的merge操作 ......
---------------------
![image-20210725220122519](03.%E7%B1%BB%E7%9A%84%E7%BB%A7%E6%89%BF/image-20210725220122519.png)
计算mro(A)方式:
mro(A) = mro( A(B,C) )
原式= [A] + merge( mro(B),mro(C),[B,C] )
mro(B) = mro( B(D,E) )
= [B] + merge( mro(D), mro(E), [D,E] ) # 多继承
= [B] + merge( [D,O] , [E,O] , [D,E] ) # 单继承mro(D(O))=[D,O]
= [B,D] + merge( [O] , [E,O] , [E] ) # 拿出并删除D
= [B,D,E] + merge([O] , [O])
= [B,D,E,O]
mro(C) = mro( C(E,F) )
= [C] + merge( mro(E), mro(F), [E,F] )
= [C] + merge( [E,O] , [F,O] , [E,F] )
= [C,E] + merge( [O] , [F,O] , [F] ) # 跳过O拿出并删除
= [C,E,F] + merge([O] , [O])
= [C,E,F,O]
原式= [A] + merge( [B,D,E,O], [C,E,F,O], [B,C])
= [A,B] + merge( [D,E,O], [C,E,F,O], [C])
= [A,B,D] + merge( [E,O], [C,E,F,O], [C]) # 跳过E
= [A,B,D,C] + merge([E,O], [E,F,O])
= [A,B,D,C,E] + merge([O], [F,O]) # 跳过O
= [A,B,D,C,E,F] + merge([O], [O])
= [A,B,D,C,E,F,O]
那既然python提供了. 为什么我们还要如此⿇烦的计算MRO呢? 因为笔
试.......你在笔试的时候, 是没有电脑的. 所以这个算法要知道. 并且简单的计算要会. 正式项⽬
开发的时候很少有⼈这么去写代码.