【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>

名称 BaseClassName必须定义于包含子类定义的作用域中,说白了就是写在一个py文件里面。 也允许用其他任意表达式代替基类名称所在的位置。 这有时也可能会用得上,例如,当基类定义在另一个模块中的时候:

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): ,不过还是推荐使用新式类的标准写法。

 

 

 

 

 

 

 

posted @ 2020-02-15 22:35  王大桃zzZ  阅读(207)  评论(0编辑  收藏  举报