1.继承只会继承父类的方法,不能继承父类的变量
2.要想继承父类的变量,需要执行父类的__init__(self)
方法
3.下划线开头的变量或方法,会被认为是受保护的,不能直接点出来,但如果强制打出来的话也一样能用,只是会有警告
4.静态方法中不能使用self,用@staticmethod声明这是一个静态方法
5.关于python中的getter和setter,比较规范的用法是
class Test2:
@property
def para1(self):
return self._para1
@para1.setter
def para1(self, value):
self._para1 = value
@para1.deleter
def para1(self):
del self._para1
if __name__ == '__main__':
instance = Test2()
print(instance.para1)
instance.para1 = 'abc'
print(instance.para1)
del instance.para1
当然,你也可以直接用实例.变量 = xxx来修改,但这样不规范
class A(object):
def __init__(self):
print('A')
super(A, self).__init__()
class B(object):
def __init__(self):
print('B')
super(B, self).__init__()
class C(A):
def __init__(self):
print('C')
super(C, self).__init__()
class D(A):
def __init__(self):
print('D')
super(D, self).__init__()
class E(B,C):
def __init__(self):
print('E')
super(E, self).__init__()
class F(C,B,D):
def __init__(self):
print('F')
super(F, self).__init__()
class G(D,B):
def __init__(self):
print('G')
super(G, self).__init__()
if __name__ == '__main__':
g = G()
print(G.mro())
f = F()
print(F.mro())
执行结果:
G
D
A
B
[<class '__main__.G'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
F
C
B
D
A
[<class '__main__.F'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>]
1.如果每个类都有正确的写super(X, self).__init__()
,那么mro顺序的所有的类的初始化方法都会执行一遍
2.如果中途有的类没有写或错误的写了super(X, self).__init__()
,那么会按mro顺序执行到执行完没写的那个类,执行结束。
3.super(X, self)
不是必须点__init__()
,可以点别的,但一般没有这么做的
4.类名.mro可以得到mro的顺序
5.这种写法可以实现每个类都被执行有且仅有一次。
如何推算mro顺序,这个问题比较复杂,目前我知道比较靠谱的说法是可以用一种所谓的公式计算出来。
mro[G](D,B)
=[G]+merge(mro[D]+mro[B]+[D,B])
=[G]+merge([D]+mro[A]+[A]+[B]+[O]+[D,B])
=[G]+merge([D]+[A]+[O]+[A]+[B]+[O]+[D,B])
接下来是提取,提取有个原则,就是所提取的不是所有列表的表尾。如[A,B,C],A是表头,B、C是表尾。提取完成后,从所有的表头删除该数据。
=[G,D]+merge([A]+[O]+[A]+[B]+[O]+[B])
=[G,D,A]+merge([O]+[B]+[O]+[B])
=[G,D,A,B]+merge([O]+[O])
=[G,D,A,B,O]
mro[F](C,B,D)
=[F]+merge(mro[C]+mro[B]+mro[D]+[C,B,D])
=[F]+merge([C]+[A]+[O]+[B]+[O]+[D]+[A]+[O]+[C,B,D])
=[F,C]+merge([A]+[O]+[B]+[O]+[D]+[A]+[O]+[B,D])
=[F,C,B]+merge([A]+[O]+[O]+[D]+[A]+[O]+[D])
=[F,C,B,D]+merge([A]+[O]+[O]+[A]+[O])
=[F,C,B,D,A,O]
也许你会开始怀疑提取顺序的问题,我的猜测是,首先一个原则肯定是按继承顺序来提取的。其次,先找继承的第1个类的子类,再找子类,这种顺序提取,类似于1→1.1→1.2→2→2.1→2.2。但如果发现所继承的多个类都继承了该子类,就不会执行该子类,转而执行下一个继承的类,这么做是为了避免重复执行同一个类的情况。假设1.2=2.2,被1和2都继承了,这时的执行顺序就是1→1.1→2→2.1→1.2(2.2)。
当然知不知道上面的顺序都无所谓,因为类名.mro可以告诉我们正确的顺序,不管你能不能想通,顺序就是这么个顺序,事实已经被设计者确定了。