python底子 — 世袭super

下面举一个例子,同样的代码使用 python2 和
python3 写的,大家注意两段程序中红色加粗的部分:

在学习python类继承的时候,有没有被super迷惑。原来这只是新式类的标志而已,并且可以改写所有上面父类的相同属性

super

1. 作用

用于子类调用父类的方法

python2的类继承使用super方法:

类名.__mro__   <==> 实例对象.__class__.__mro__

2. 操作

# super

class A(object):
    def __init__(self):
        print('enter A')
        print('exit A')

class B(A):
    def __init__(self):
        print('enter B')
        super(B, self).__init__()
        print('exit B')

class C(A):
    def __init__(self):
        print('enter C')
        super(C, self).__init__()
        print('exit C')

class D(C, B): # 
    def __init__(self):
        print('enter D')
        super(D, self).__init__()
        print('exit D')

if __name__ == '__main__':
    d = D()

# enter D
# enter C
# enter B
# enter A
# exit A
# exit B
# exit C
# enter D
 1 #-*-  coding:utf-8 -*-
 2 '''
 3 Created on 2018年8月27日
 4 
 5 @author: anyd
 6 '''
 7 import random as r
 8 
 9 class Fish(object):
10     def __init__(self):
11         self.x = r.randint(0, 10)
12         self.y = r.randint(0, 10)
13             
14     def move(self):
15         #这里主要演示类的继承机制,就不考虑检查场景边界和移动方向的问题
16         #假设所有鱼都是一路向西游
17         self.x -= 1
18         print "我的位置是:", self.x, self.y
19 
20 class Goldfish(Fish):
21     pass
22 
23 class Carp(Fish):
24     pass
25 
26 class Salmon(Fish):
27     pass
28 
29 #上边几个都是食物,食物不需要有个性,所以直接继承Fish类的全部属性和方法即可
30 #下边定义鲨鱼类,这个是吃货,除了继承Fish类的属性和方法,还要添加一个吃的方法
31 
32 class Shark(Fish):
33     def __init__(self):
34         super(Shark,self).__init__()       
35         self.hungry = True
36 
37     def eat(self):
38         if self.hungry:
39             print "吃货的梦想就是天天有的吃^_^"
40             self.hungry = False
41         else:
42             print "太撑了,吃不下了!"
43             
44 aa = Shark()
45 aa.move()

super().__init__ <==>super(类名{所要继承的父类的类名},
self).__init__()

输出如下:

print(Dog.__mro__)#查看继承关系(其父类)

我的位置是: 8 2

print(d.__class__.__mro__)

  

理解 Python super mro

python3的类继承使用super方法:

最后的最后,提醒大家. 什么 super 啊,MRO 啊,都是针对 new-style
class。如果不是 new-style class,就老老实实用父类的类名去调用函数吧。

 1 #-*-  coding:utf-8 -*-
 2 '''
 3 Created on 2018年8月27日
 4 
 5 @author: anyd
 6 '''
 7 import random as r
 8 
 9 class Fish(object):
10     def __init__(self):
11         self.x = r.randint(0, 10)
12         self.y = r.randint(0, 10)
13             
14     def move(self):
15         #这里主要演示类的继承机制,就不考虑检查场景边界和移动方向的问题
16         #假设所有鱼都是一路向西游
17         self.x -= 1
18         print ("我的位置是:", self.x, self.y)
19 
20 class Goldfish(Fish):
21     pass
22 
23 class Carp(Fish):
24     pass
25 
26 class Salmon(Fish):
27     pass
28 
29 #上边几个都是食物,食物不需要有个性,所以直接继承Fish类的全部属性和方法即可
30 #下边定义鲨鱼类,这个是吃货,除了继承Fish类的属性和方法,还要添加一个吃的方法
31 
32 class Shark(Fish):
33     def __init__(self):
34         super().__init__()       
35         self.hungry = True
36 
37     def eat(self):
38         if self.hungry:
39             print ("吃货的梦想就是天天有的吃^_^")
40             self.hungry = False
41         else:
42             print ("太撑了,吃不下了!")
43             
44 aa = Shark()
45 aa.move()

[初学python]新类(new-style class)

输出如下:

我的位置是: 7 4

换句话说,我们可以做出这样的定义:元类为types.ClassType的类是classic
classes;元类为type的类是new-style classes。

  

另外,根据后面的结论,我们还可以预先给出new-style
classes的另一种定义:object和所有直接或间接以它为基类的类是new-style
classes。这里的object是一个new-style class的内建类型,
它作为所有new-style classes的

super方法具体使用注意事项可以参考官方的指导文档,里面有详细的使用例子,但个人觉得这种super方法不太容易让人看得舒服,个人比较偏好采用未绑定的方法来写,这样就不管是python2 还是
python3,都是没有问题的。如下:

1 class Shark(Fish):
2     def __init__(self):
3         Fish.__init__(self)     
4         self.hungry = True

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注