当前位置: 移动技术网 > IT编程>脚本编程>Python > 继承

继承

2018年11月14日  | 移动技术网IT编程  | 我要评论

xnmsn,姚子羚吻戏,89i98

一、判断继承

1. issubclass

  • 判断xxx类是否是yyy类型的子类
  • 可以隔代判数
class base:
    pass

class foo(base):
    pass

class bar(foo):
    pass

print(issubclass(bar, foo))   # true
print(issubclass(foo, bar))   # false
print(issubclass(bar, base))  # true

 二、多继承

  • python支持多继承,一个类可以拥有多个父类
  • 经典类:在python2.2之前版本使用的是经典类,经典类在基类的根如果什么都不写,不示继承xxx
  • 新式类:在python2.2之后版本使用的是新式类,新式类的特点是基类的根是object
  • python3使用的都是新式类,如果基类谁都不继承。那这个类会默认继承object

三、mro

    在多继承中,当多个父类出现了重名方法时,此时就涉及到如何查找父类方法的问题,即mro(method resolution order)问题。

    在python中,不同的版本中使用的是不同的算法来完成mro的

1. 经典类的mro

  • 采用的是树型结构的深度优先遍历
  • 深度优先遍历:从左往右,一条道走到黑
class a:
    pass

class b(a):
    pass

class c(a):
    pass

class d(b, c):
    pass

class e:
    pass

class f(e, b):
    pass

class g(f, d):
    pass

class h:
    pass

class foo(h, g):
    pass

 继承关系图如下:

 

图1  继承关系图

类的mro:foo ---> h ---> g ---> f ---> e ---> b ---> a --->d ---> c

2. 新式类的mro—c3算法

官方网址:

步骤:

  • 先拆分
  • 再合并:从下向上合并,拿出每一项的头和后一项的身体进行比较,如果出现了,就过,从后一项的头继续去比较,如果不出现就拿出来
class a:
    pass
class b(a):
    pass
class c(a):
    pass
class d(b, c):
    pass
class e(c, a):
    pass
class f(d, e):
    pass
class m(f, e):
    pass
class n:
    pass
class p(m,n):
    pass
class g(p):
    pass
class o:
    pass
class x(o):
    pass
class h(g, x, f):
    pass
print(h.__mro__)

结果:
(<class '__main__.h'>, <class '__main__.g'>, <class '__main__.p'>, <class '__main__.m'>, <class '__main__.x'>, <class '__main__.f'>, <class '__main__.d'>, <class '__main__.b'>, <class '__main__.e'>, <class '__main__.c'>, <class '__main__.a'>, <class '__main__.n'>, <class '__main__.o'>, <class 'object'>)

1) 先拆分:设l为查找方法的mro顺序

l(h) = h + l(g) + l(x) + l(f) + gxf

 

l(g) = g + l(p) + p

l(x) = x + l(o) + o

l(f) = f + l(d) + l(e) + de

 

l(p) = p + l(m) + l(n) + mn

l(d) = d + l(b) + l(c) + bc

l(e) = e + l(c) + a + ca

 

l(m) = m + l(f) + l(e) + fe

2) 合并:

l(h) = h + l(g) + l(x) + l(f) + gxf     ====>hgpmxfdbecano

 

l(g) = g + l(p) + p                                ====>gpmfdbecan

l(x) = x + l(o) + o                                ====>xo

l(f) = f + l(d) + l(e) + de                   ====>fdbeca

 

l(p) = p + l(m) + l(n) + mn                 ====>pmfdbecan

l(d) = d + l(b) + l(c) + bc                  ====>dbca

l(e) = e + l(c) + a + ca                       ====>eca

 

l(m) = m + l(f) + l(e) + fe                  ====>mfdbeca

l(c) = c + l(a)                                     ====>ca

l(n) = n                                               ====>n

l(b) = b + l(a) + a                              ====>ba

类的mro:h--->g--->p--->m--->x--->f--->d--->b--->e--->c--->a--->n--->o

四、super

1. 访问父类的初始化方法

    这样子类和父类初始化方法中相同的代码可不必都写,直接用父类的就好

class base(object):

    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c


class foo(base):

    def __init__(self, a, b, c, d):
        super().__init__(a, b, c)
        self.d = d


f = foo(1, 2, 3, 4)
print(vars(f))    # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

 

2. 实现子类方法调用父类(mro)中的方法

  • super().方法名():执行mro中下一个方法
  • super(类名,self).方法名():定位到该类,执行mro中该类下一个类的方法
class biology(object):
    def move(self):
        print("----biology-----")


class animal(biology):
    def move(self):
        print("-----animal-----")


class cat(animal):
    def move(self):
        super().move()   # 找mro中的下一个
        print("-----cat-----")


c = cat()
c.move()


# 结果:
# -----animal-----
# -----cat-----

 

class biology(object):
    def move(self):
        print("----biology-----")


class animal(biology):
    def move(self):
        print("-----animal-----")


class cat(animal):
    def move(self):
        super(animal, self).move()   # 定位到animal,找animal下一个
        print("-----cat-----")


c = cat()
c.move()


# 结果:
# ----biology-----
# -----cat-----

 

3. 应用

class init(object):
    def __init__(self, v):
        print("init")
        self.val = v


class add2(init):
    def __init__(self, val):
        print("add2")
        super(add2, self).__init__(val)
        print(self.val)
        self.val += 2


class mult(init):
    def __init__(self, val):
        print("mult")
        super(mult, self).__init__(val)
        self.val *= 5


class haha(init):
    def __init__(self, val):
        print("哈哈")
        super(haha, self).__init__(val)
        self.val /= 5


class pro(add2,mult,haha): #
    pass


class incr(pro):
    def __init__(self, val):
        super(incr, self).__init__(val)
        self.val += 1


p = incr(5)
print(p.val)   # add2 mult 哈哈 init 5.0 8.0

c = add2(2)

print(c.val) # add2 init 2 4

 

mro:

1)  incr: incr ---> pro ---> add2 ---> mult ---> haha ---> init

2) add2: add2 ---> init

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网