在__new__中修改kwargs没有作用于__init__
来源:8-4 __new__和__init__的区别

大野和我3326249
2018-10-30
如上图demo中,我在__new__魔法函数中修改了kwargs, 但是似乎并没有作用于__init__构造函数里面
程序运行的结果为
在__new__方法里的 kwargs 与 __init__的 kwargs的ID一致 ,__new__方法先于 __init__方法被调用 为什么会出现这种现象呢?
5回答
-
这是我理解class创建实例的调用流程,细节方面肯定有很多不对之处,但是通过断点调试,调用顺序就是这样。
如果不释放的那上层调用者entry的kwargs的id应该和init和new中的id是一样的。这里正好相差4,应该是类似于其他语言的函数调用栈。
new应该是创建对象,而init是初始化对象。这里甚至可以不设置init,而是使用__new__中代码初始化变量,比如如下代码:
012018-11-01 -
慕运维5049730
2018-11-05
回答的很好,很厉害
022018-11-05 -
pineryme
2018-11-01
这里可以截图,再来发一个实验,哈哈哈:
执行结果如下:
**kwargs是形参,kwargs是实参。
042018-11-01 -
Jazz_Qi
2018-11-01
反正我也没懂,两个函数都是用同一个形参,但是两个函数是有先后运行的循序,在调用父类的__new__()前先把形参的内容修改应该影响实例化的过程,但结果是没有任何改变。我猜想这是python的策略,不给修改传入的参数。实现过程很可能是,函数中**kwargs所生成的字典是一回事,__new__和__init__中传入的参数是另一回事,前者是一种方便程序员编程的设计,后者是类实例化和编译过程更底层的策略造成的(可能根本没有用到那个字典),实际为何需要老师和高手解答。
00 -
pineryme
2018-10-30
实际上__new__和__init__的调用流程应该是类似如上,super().__new__()并不会调用__init__(),可以自己用print语句测试一下,所以new中的kwargs在调用完成之后就释放了,当之后再调用init时kwargs重新分配,所以两者的地址恰好相等,但是此时的kwargs和new中的kwargs已经不是同一个kwargs了。
简单的测试一下:
a = {'a': 1}
print(id(a))
del a
try:
print(a)
except NameError:
pass
a = {'a': 2}
print(id(a))两次的地址是一样的,但是两次的变量已经不是同一个变量了。
0192018-11-01
相似问题