【python之路】【之前没搞明白】3面向对象(继承)
文献:
https://book.apeland.cn/details/157/
https://docs.python.org/zh-cn/3/tutorial/classes.html#a-word-about-names-and-objects
1 继承的语法
继承用在这里就是字面意思,一个类可以继承另一个类的属性与方法。
“一个类”就是子类、派生类
“另一个类”就是父类、超类、基类
class DerivedClassName(BaseClassName): <statement-1> ... <statement-N>
名称
必须定义于包含子类定义的作用域中,说白了就是写在一个py文件里面。 也允许用其他任意表达式代替基类名称所在的位置。 这有时也可能会用得上,例如,当基类定义在另一个模块中的时候:BaseClassName
class DerivedClassName(modname.BaseClassName):
试了一下,在用之前一定在正在执行的py文件中先导入modname模块才行。
# 这是modname.py文件
class BaseClassName: def test(self): print('从modname的BaseClassName来的')
# 这是正在执行的py文件 import modname class DerivedClassName(modname.BaseClassName): def show(self): super().test() if __name__ == '__main__': d = DerivedClassName() d.show()
结果: 从modname的BaseClassName来的
1.1 子类和父类中的属性和方法引用的顺序
1、找子类的属性或方法,有则直接引用,无则2
2、再找父类的属性或方法,有则直接引用,无则3
3、如果父类也有父类 的话,继续递归的应用下去
1.2 子类重写父类的方法
官方文档所所得最直接的方法: BaseClassName.methodname(self, arguments)
还可以用 super().methodName()
class Base: def fun_1(self,arg): print('基类方法1执行结果:%s' %arg) def fun_2(self): print('基类方法2') class Sub(Base): def fun_3(self,arg): Base.fun_1(self, arg) #第一种觉得不会错 def fun_4(self): super().fun_2() #第二种,在多继承时要注意顺序 print('子类调用了一次基类方法fun_2') #对基类方法的扩展 if __name__ == '__main__': s = Sub() s.fun_3(arg='dashabi') #基类方法1执行的结果是 dashabi s.fun_4() #基类方法2
结果:
基类方法1执行结果:dashabi
基类方法2
子类调用了一次基类方法fun_2
1.3 两个内置函数的使用
-
使用
isinstance()
来检查一个实例的类型:isinstance(obj, int)
仅会在obj.__class__
为int
或某个派生自int
的类时为True
。 -
使用
issubclass()
来检查类的继承关系:issubclass(bool, int)
为True
,因为bool
是int
的子类。 但是,issubclass(float, int)
为False
,因为float
不是int
的子类。
2 多继承
多继承时,继承顺序很重要,分为2种:
深度优先:从下到上,从最下面的子类到最上面的父类
广度优先:从左到右,类(基类左,基类右)的括号里面,从左往右
python3内部使用的是一个混合的方法,C3算法(看的太累,https://www.python.org/download/releases/2.3/mro/)。
很复杂,可能要花很多时间去搞清楚,但是没必要。直接调用 mro() python会告诉你顺序的。
class A: def test(self): # A print('A') # / / \ \ class B1(A): # B1 B2 B3 B4 def test(self): # \ / \ / print('B1') # C1 C2 class B2(A): # \ / def test(self): # D print('B2') class B3(A): def test(self): print('B3') # D > C1 > B1 > B2 > C2 > B3 > B4 > A > 'object' class B4(A): def test(self): # object类,是python中所有类的基类,万类归宗就是object类 print('B4') class C1(B1,B2): def test(self): print('C1') class C2(B3,B4): def test(self): print('C2') class D(C1,C2): def test(self): print('D') if __name__ == '__main__': print(D.mro()) d = D() d.test()
这里和Alex视频里面讲的顺序好像有点区别,我也不知道问题在哪里。
3 补充的知识点:经典类和新式类
python2定义类的为经典类和python3定义类的为新式类:
经典类:class Foo:
新式类:class Foo( object):
但是在python3中,对新式类有个简便写法,就是 class Foo: ,本质上还是 class Foo( object): ,不过还是推荐使用新式类的标准写法。