__new__/__init__/super的用法详解
__new__讲解:
__new__称作构造方法,属于类方法,用于创建一个实例对象。必须要有返回值,如果返回的是本类的实例,则返回实例对象会自动调用__init__方法(如果定义了该方法的话),如果返回的不是本类实例,则不会调用本类的__init__方法。
class Test:
def __init__(self):
print("TEST __init__")
class A:
def __new__(cls, *args, **kwargs):
print("enter __new__")
obj = object.__new__(cls, *args, **kwargs) # 测试1
obj = object.__new__(Test, *args, **kwargs) # 测试2
print(obj, obj.__class__)
return obj
def __init__(self):
print("enter __init__")
self.n = 2
# 测试1:把测试2代码注释掉
A()
#输出:
'''
enter __new__
<__main__.A object at 0x00000000028F6668> <class '__main__.A'>
enter __init__
'''
# 测试2:把测试1代码注释掉
A()
# 输出:
'''
enter __new__
<__main__.Test object at 0x00000000028D6668> <class '__main__.Test'>
'''
super讲解:
super()主要应用在类的继承。super()返回的是根据继承树解析最近的类对象,继承树可以通过cls.mro(), 或者cls.__mro__拿到。super(fatherclass, self)可以指定从哪个类对象之后的继承树开始查找。
class A:
def __init__(self):
print("A.__init__")
super().__init__()
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
print("B.__init__")
super().__init__()
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
self.n += 3
class C(A):
def __init__(self):
print("C.__init__")
super().__init__()
self.n = 4
def add(self, m):
print('self is {0} @C.add'.format(self))
super().add(m)
self.n += 4
class D(B, C):
def __init__(self):
print("D.__init__")
super().__init__()
self.n = 5
def add(self, m):
print('self is {0} @D.add'.format(self))
super().add(m)
self.n += 5
print(D.mro())
d = D()
d.add(2)
print(d.n)
# 输出:
'''
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
D.__init__
B.__init__
C.__init__
A.__init__
self is <__main__.D object at 0x00000000028C1A90> @D.add
self is <__main__.D object at 0x00000000028C1A90> @B.add
self is <__main__.D object at 0x00000000028C1A90> @C.add
self is <__main__.D object at 0x00000000028C1A90> @A.add
19
'''