什么是 super?
super() 函数是用于调用父类 (超类) 的一个方法.
super 是用来解决多重继承问题的, 直接用类名调用父类方法在使用单继承的时候没问题, 但是如果使用多继承, 会涉及到查找顺序 (MRO), 重复调用(钻石继承) 等种种问题.
MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表.
语法
以下是 super() 方法的语法:
super(type[, object-or-type])
参数
.type -- 类.
.object-or-type -- 类, 一般是 self
Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx :
Python3.x 实例:
- class A:
- pass
- class B(A):
- def add(self, x):
- super().add(x)
Python2.x 实例:
- class A(object): # Python2.x 记得继承 object
- pass
- class B(A):
- def add(self, x):
- super(B, self).add(x)
具体应用示例:
举个例子
- class Foo:
- def bar(self, message):
- print(message)
- >>> Foo().bar("Hello, Python.")
Hello, Python.
当存在继承关系的时候, 有时候需要在子类中调用父类的方法, 此时最简单的方法是把对象调用转换成类调用, 需要注意的是这时 self 参数需要显式传递, 例如:
- class FooParent:
- def bar(self, message):
- print(message)
- class FooChild(FooParent):
- def bar(self, message):
- FooParent.bar(self, message)
- >>> FooChild().bar("Hello, Python.")
Hello, Python.
这样做有一些缺点, 比如说如果修改了父类名称, 那么在子类中会涉及多处修改, 另外, Python 是允许多继承的语言, 如上所示的方法在多继承时就需要重复写多次, 显得累赘. 为了解决这些问题, Python 引入了 super()机制, 例子代码如下:
- class FooParent:
- def bar(self, message):
- print(message)
- class FooChild(FooParent):
- def bar(self, message):
- super(FooChild, self).bar(message)
- >>> FooChild().bar("Hello, Python.")
- Hello, Python
表面上看 super(FooChild, self).bar(message)方法和 FooParent.bar(self, message)方法的结果是一致的, 实际上这两种方法的内部处理机制大大不同, 当涉及多继承情况时, 就会表现出明显的差异来, 直接给例子:
代码一:
- class A:
- def __init__(self):
- print("Enter A")
- print("Leave A")
- class B(A):
- def __init__(self):
- print("Enter B")
- A.__init__(self)
- print("Leave B")
- class C(A):
- def __init__(self):
- print("Enter C")
- A.__init__(self)
- print("Leave C")
- class D(A):
- def __init__(self):
- print("Enter D")
- A.__init__(self)
- print("Leave D")
- class E(B, C, D):
- def __init__(self):
- print("Enter E")
- B.__init__(self)
- C.__init__(self)
- D.__init__(self)
- print("Leave E")
- E()
结果为:
- Enter E
- Enter B
- Enter A
- Leave A
- Leave B
- Enter C
- Enter A
- Leave A
- Leave C
- Enter D
- Enter A
- Leave A
- Leave D
- Leave E
执行顺序很好理解, 唯一需要注意的是公共父类 A 被执行了多次.
代码二:
- class A:
- def __init__(self):
- print("Enter A")
- print("Leave A")
- class B(A):
- def __init__(self):
- print("Enter B")
- super(B, self).__init__()
- print("Leave B")
- class C(A):
- def __init__(self):
- print("Enter C")
- super(C, self).__init__()
- print("Leave C")
- class D(A):
- def __init__(self):
- print("Enter D")
- super(D, self).__init__()
- print("Leave D")
- class E(B, C, D):
- def __init__(self):
- print("Enter E")
- super(E, self).__init__()
- print("Leave E")
- E()
结果:
- Enter E
- Enter B
- Enter C
- Enter D
- Enter A
- Leave A
- Leave D
- Leave C
- Leave B
- Leave E
在 super 机制里可以保证公共父类仅被执行一次, 至于执行的顺序, 是按照 MRO(Method Resolution Order): 方法解析顺序 进行的
来源: http://www.bubuko.com/infodetail-2985741.html