采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
如上图demo中,我在__new__魔法函数中修改了kwargs, 但是似乎并没有作用于__init__构造函数里面 程序运行的结果为 在__new__方法里的 kwargs 与 __init__的 kwargs的ID一致 ,__new__方法先于 __init__方法被调用 为什么会出现这种现象呢?
这是我理解class创建实例的调用流程,细节方面肯定有很多不对之处,但是通过断点调试,调用顺序就是这样。
如果不释放的那上层调用者entry的kwargs的id应该和init和new中的id是一样的。这里正好相差4,应该是类似于其他语言的函数调用栈。
new应该是创建对象,而init是初始化对象。这里甚至可以不设置init,而是使用__new__中代码初始化变量,比如如下代码:
非常感谢!
回答的很好,很厉害
给我自己点个赞
再给我自己点个赞
这里可以截图,再来发一个实验,哈哈哈:
执行结果如下:
**kwargs是形参,kwargs是实参。
怎么截图??害我一直手写代码
好像回复不能截图 回答才可以截图
不过这就就好像解决了以上问题,手动滑稽。。。
反正我也没懂,两个函数都是用同一个形参,但是两个函数是有先后运行的循序,在调用父类的__new__()前先把形参的内容修改应该影响实例化的过程,但结果是没有任何改变。我猜想这是python的策略,不给修改传入的参数。实现过程很可能是,函数中**kwargs所生成的字典是一回事,__new__和__init__中传入的参数是另一回事,前者是一种方便程序员编程的设计,后者是类实例化和编译过程更底层的策略造成的(可能根本没有用到那个字典),实际为何需要老师和高手解答。
实际上__new__和__init__的调用流程应该是类似如上,super().__new__()并不会调用__init__(),可以自己用print语句测试一下,所以new中的kwargs在调用完成之后就释放了,当之后再调用init时kwargs重新分配,所以两者的地址恰好相等,但是此时的kwargs和new中的kwargs已经不是同一个kwargs了。
简单的测试一下:
a = {'a': 1}print(id(a))del atry: print(a)except NameError: passa = {'a': 2}print(id(a))
两次的地址是一样的,但是两次的变量已经不是同一个变量了。
如果在__init__(*args, *kwargs)与 __new__(*args, *kwargs)中的kwargs经历了一次重新分配的过程 我们在__new__中传入 实例化需要的参数的意义是什么 如果通过实例的某些属性(实例变量)去计算类属性(类变量)的值,是不是不太符合面向对象的编程思想呢?
并且在您给出的示例中,在CPython的解释器中id是一致的,但是在iPython解释器中id不一致 在__init__和__new__中 id总是一致
而且我认为您给出的示例的运行结果,应该是CPython中的BUG,不符合常理,不知道我是否理解错了。。。
登录后可查看更多问答,登录/注册
socket编程/多线程/多进程/线程池/asyncio并发编程/协程和异步IO
1.2k 31
1.1k 24
1.1k 16
1.4k 10
1.1k 9