请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

在__new__中修改kwargs没有作用于__init__

图片描述
如上图demo中,我在__new__魔法函数中修改了kwargs, 但是似乎并没有作用于__init__构造函数里面
程序运行的结果为
图片描述
在__new__方法里的 kwargs 与 __init__的 kwargs的ID一致 ,__new__方法先于 __init__方法被调用 为什么会出现这种现象呢?

正在回答

5回答

这是我理解class创建实例的调用流程,细节方面肯定有很多不对之处,但是通过断点调试,调用顺序就是这样。

//img1.sycdn.imooc.com//szimg/5bd9b0930001fae504860488.jpg

//img1.sycdn.imooc.com//szimg/5bd9b0c00001f5a302800176.jpg

如果不释放的那上层调用者entry的kwargs的id应该和init和new中的id是一样的。这里正好相差4,应该是类似于其他语言的函数调用栈。

new应该是创建对象,而init是初始化对象。这里甚至可以不设置init,而是使用__new__中代码初始化变量,比如如下代码:

//img1.sycdn.imooc.com//szimg/5bd9b1e80001c8c303010309.jpg


0 回复 有任何疑惑可以回复我~
慕运维5049730 2018-11-05 13:08:57

回答的很好,很厉害

0 回复 有任何疑惑可以回复我~
pineryme 2018-11-01 11:57:55

这里可以截图,再来发一个实验,哈哈哈:

https://img1.sycdn.imooc.com//szimg/5bda791400012dd403120356.jpg

执行结果如下:

https://img1.sycdn.imooc.com//szimg/5bda79330001242301920083.jpg

**kwargs是形参,kwargs是实参。

0 回复 有任何疑惑可以回复我~
  • 提问者 大野和我3326249 #1
    怎么截图??害我一直手写代码
    回复 有任何疑惑可以回复我~ 2018-11-01 12:05:19
  • 提问者 大野和我3326249 #2
    好像回复不能截图 回答才可以截图
    回复 有任何疑惑可以回复我~ 2018-11-01 12:05:54
  • 提问者 大野和我3326249 #3
    不过这就就好像解决了以上问题,手动滑稽。。。
    回复 有任何疑惑可以回复我~ 2018-11-01 12:09:49
Jazz_Qi 2018-11-01 10:50:23

反正我也没懂,两个函数都是用同一个形参,但是两个函数是有先后运行的循序,在调用父类的__new__()前先把形参的内容修改应该影响实例化的过程,但结果是没有任何改变。我猜想这是python的策略,不给修改传入的参数。实现过程很可能是,函数中**kwargs所生成的字典是一回事,__new__和__init__中传入的参数是另一回事,前者是一种方便程序员编程的设计,后者是类实例化和编译过程更底层的策略造成的(可能根本没有用到那个字典),实际为何需要老师和高手解答。

0 回复 有任何疑惑可以回复我~
pineryme 2018-10-30 22:28:41

//img1.sycdn.imooc.com//szimg/5bd868fa0001811702380231.jpg

实际上__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))

两次的地址是一样的,但是两次的变量已经不是同一个变量了。

0 回复 有任何疑惑可以回复我~
  • 提问者 大野和我3326249 #1
    如果在__init__(*args, *kwargs)与 __new__(*args, *kwargs)中的kwargs经历了一次重新分配的过程 我们在__new__中传入 实例化需要的参数的意义是什么 如果通过实例的某些属性(实例变量)去计算类属性(类变量)的值,是不是不太符合面向对象的编程思想呢?
    回复 有任何疑惑可以回复我~ 2018-10-31 11:28:49
  • 提问者 大野和我3326249 #2
    并且在您给出的示例中,在CPython的解释器中id是一致的,但是在iPython解释器中id不一致
    在__init__和__new__中 id总是一致
    回复 有任何疑惑可以回复我~ 2018-10-31 11:43:02
  • 提问者 大野和我3326249 #3
    而且我认为您给出的示例的运行结果,应该是CPython中的BUG,不符合常理,不知道我是否理解错了。。。
    回复 有任何疑惑可以回复我~ 2018-10-31 11:50:36
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信