最近我在学习 python 魔术方法,__new__
因为我们总是重写它
class A:
def __new__(cls):
# ......
return super().__new__(cls)
def __init__(self):
# .....
此方法将返回一个 A 对象,然后 A 将执行__init__
。
所以,我尝试以下脚本
class A:
def __init__(self):
print('A.__init__')
self.a = 20
class B:
def __new__(cls):
print('B.__new__')
return super().__new__(A)
def __init__(self):
print('B.__init__')
self.b = 30
t = B()
print(type(t))
然后我得到结果
B.__new__
<class '__main__.A'>
在我看来,B.__new__
返回一个对象,因为它显示的话,就应该执行A.__init__
的方法,但实际上既没有A.__init__
,也不B.__init__
执行,对象t
是一个对象,但它没有什么涉及到A或B,这让我困惑,什么是cls
在__new__
方法步骤为?
在我看来,
B.__new__
返回一个 A 对象,就像它显示的那样,然后它应该执行A.__init__
方法
这种假设是不正确的。让我们看看创建实例的代码。在python中,这将是type.__call__
方法。C 实现可以在这里找到
发生的三个有趣的步骤是:
或者在python代码中:
# t = B() is roughly equivalent to
t = B.__new__() # which returns `A.__new__()`
if ìssubclass(type(t), B): # False
t.__init__() # never called
B.__new__
然而,您的实现会创建一个类型为 的对象A
。因此,issubclass
检查失败并且 no__init__
被调用。
总结:B.__init__
不叫,因为B.__new__
没有创造类型的对象B
并A.__init__
没有被调用,因为类对象A
是不负责创建实例(B
是)。
最终结果是,这t
是一个类的实例,A
但它__init__
没有被调用。这t
就是未初始化的原因。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句