以下代码 是解决钻石问题的多重调用及其他潜在风险!转载请注明出处,谢谢!
__Author__ = 'KaiAowisySun'
import os
if __name__ != '__main__':
print(f"→ {os.path.abspath(__file__)} !")
#【钻石继承】
# 继承图: mro图:
# Person Person
# ↙ ↘ ↖
# Father Mother Father → Mother
# ↘ ↙ ↖
# Son Son
class Person(object):
# tst0='test0' # 类属性,可以继承
def __init__(self, name):
self.__name = name
# self.tst1='test1' # 实例属性(非参数化),可以继承
print("Person init")
def get_name(self):
return self.__name
def func1_cm(self): # 重名函数,与Mother中的重名
print('Person func1_cm()')
class Mother(Person):
def __init__(self, job, *args): # 另外如果参数中有list等类型,要再加上**kargs 。(这里的*扩展参数实际是为了多继承时的super()调用,可以让多继承中的多各类的参数衔接上)
super(Mother, self).__init__(*args)
# 这两句也可以替换为下两句↓,补全父类参数name,使得更明显得看出是要传入哪些参数。(但实际没必要,上两句得*args会自动获取父类参数。)
# def __init__(self, name, job, *args):
# super(Mother, self).__init__(name,*args)
self.__job = job
print("Mother init")
def get_job(self):
return self.__job
def func1_cm(self): # 重名函数
print('Mother func1_cm()')
def func2_cm(self): # 重名函数,与Father中的重名
print('Mother func2_cm()')
class Father(Person):
def __init__(self, age, *args):
super(Father, self).__init__(*args)
# def __init__(self, name, age):
# super(Father, self).__init__(name)
self.__age = age
print("Father init")
def get_age(self):
return self.__age
def func2_cm(self): # 重名函数
print('Father func2_cm()')
# __Author__ = 'KaiAowisySun'
# ↑单继承可用*args代替父类参数;↓多继承要把参数写全。
class Son(Father, Mother):
# def __init__(self, gender, *args):
# super(Son, self).__init__(*args)
def __init__(self, name, age, job, gender):
# super(Son, self).__init__(name, age, job)
super().__init__(name, age, job) # Python3 可以省略super()参数,等同上句。
self.__gender = gender
print("Son init")
def get_gender(self):
return self.__gender
print(Son.mro()) # mro就是类的方法解析顺序表, 即继承父类方法时的顺序表。
wo = Son('tom', 22, 'teacher', 'male')
print(wo.get_name(), wo.get_age(), wo.get_job(), wo.get_gender())
## print(wo.__name) # err. 类内部属性不可访问
# print(wo.tst0) # 实例属性(非参数化),可以继承
# print(wo.tst1) # 实例属性,可以继承(非参数化)
wo.func1_cm() # 多继承中若有同名方法继承,按顺序继承mro最近的。
wo.func2_cm()
# MRO/mro :Method Resolution Order,方法解析顺序,即继承顺序。
# 无论是 构造函数__init__(本类中无构造函数前提下)、属性、方法 继承都遵循mro 。
# 且构造函数的继承,在
# python3 中:
# 继承都以广度优先。
# (如在此例中,如果Son中没有构造函数__init__,则先去父类Fatjer中寻找,若无,再去Mother中找,若无,再去Person中找。并且(找到后)只继承一个父类中的构造函数。)
# python2 中:
# 经典类写法继承以深度优先;
# 新式类写法继承以广度优先。<font size=5>
转载请注明出处,谢谢!