超类方法
super(type[, object-or-type]):返回一个代理对象,并将调用方法委派给父类或者type的兄弟类。__mro__
属性列出getattr()
和super()
的方法解析搜索顺序。
super():
与super(class, <first argument>)相同;super(type):
返回未绑定的super对象super(type, obj):
返回绑定的super对象,必须保证isinstance(obj, type)
为真super(type, type2):
返回绑定的super对象,必须保证issubclass(type2, type)
为真,多用于classmethods
object指实例化的对象,如self,person=Person();type指未实例化的类,如Person。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
class Student(Person):
def __init__(self, name, age, no):
# 调用父类__init__方法
# 等价于super(Student, self).__init__(name=name, age=age)
# 等价于Person.__init__(self, name=name, age=age)
super().__init__(name=name, age=age)
self.no = no
student = Student(name="Song", age=21, no=12345)
若继承关系为A -> B -> C
,表示C
继承B
,B
继承A
,自有方法和类方法调用如下:
class A:
_cls_name = "A"
def __init__(self):
self._self_name = "a"
def self_name(self):
print(f"A-{self._self_name}")
@classmethod
def cls_name(cls):
print(f"A-{cls._cls_name}")
class B(A):
_cls_name = "B"
def __init__(self):
super().__init__()
self._self_name = "b"
def self_name(self):
print(f"B-{self._self_name}")
@classmethod
def cls_name(cls):
print(f"B-{cls._cls_name}")
class C(B):
_cls_name = "C"
def __init__(self):
super().__init__()
self._self_name = "c"
def self_name(self):
print(f"C-{self._self_name}")
@classmethod
def cls_name(cls):
print(f"C-{cls._cls_name}")
col -row | A | B | C |
---|---|---|---|
A | A.cls_name() | 超类不能使用子类方法 | 超类不能使用子类方法 |
B | super(B, B).cls_name() | B.cls_name() | 超类不能使用子类方法 |
C | super(B, C).cls_name() | super(C, C).cls_name() | C.cls_name() |
a | A.self_name(a) a.self_name() | B.self_name(a) | C.self_name(a) |
b | A.self_name(b) super(B, b).self_name() | B.self_name(b) b.self_name() | C.self_name(a) |
c | A.self_name© super(B, c).self_name() super(B, C).self_name© super(B, B).self_name© | B.self_name© super(C, c).self_name() super(C, C).self_name© | C.self_name(a) c.self_name() |
钻石继承
"""
Base
/ \
/ \
A B
\ /
\ /
C
"""
class Base:
def __init__(self):
print('Base.__init__')
class A(Base):
def __init__(self):
super().__init__()
print('A.__init__')
class B(Base):
def __init__(self):
super().__init__()
print('B.__init__')
class C1(A, B):
def __init__(self):
A.__init__(self)
B.__init__(self)
print('C1.__init__')
class C2(A, B):
def __init__(self):
super().__init__()
print('C2.__init__')
继承多个实例时,python按照mro
表解法方法调用顺序,左侧父类方法优先于右侧父类(初始化是从)。
默认从右向左初始化,左侧同名方法会覆盖右侧父类的方法。
C1()
"""
Base.__init__
B.__init__
A.__init__
Base.__init__
B.__init__
C1.__init__
"""
C2()
"""
Base.__init__
B.__init__
A.__init__
C2.__init__
"""
print(C1.mro())
"""
[<class '__main__.C1'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
"""