在多年开发和教学 Python 的过程中,有一个 bug,出现的频率非常高,经常有人会踩坑:
person = {'name': '', 'id': 0} team = [] for i in range(3): x = person x['id'] = i team.append(x) team[0]['name'] = 'Jack' team[1]['name'] = 'Pony' team[2]['name'] = 'Crossin' print(team[1])
如果觉得这个输出结果是 {‘name’: ‘Pony’, ‘id’: 1} ,那么就掉进这个坑里了。
如果真的运行一下就会发现,team里面三个都是 {‘name’: ‘Crossin’, ‘id’: 2} , 而且,如果之后再更改任何一个的 name 或 id 属性,另外两个也会跟着变。
那么为什么呢?
在 Python 中,要把变量想象成一个标签,而不是一个容器!
什么意思?在某些语言中,变量确实像一个“容器”,你定义了某种类型的变量,就给你分配好这个容器,之后你给变量赋值,就像是往容器里装入不同的内容,但容器还是那个容器,不会变。你创建3个容器,赋给一样的值,他们也还是3个独立的容器。
但在 Python 中,这个理解是错误的!
Python 中的变量像是一个“标签”,你给一个变量赋值,就是把这个标签贴在一个对象上;重新赋值,就是撕下标签帖到另一个对象上。
给3个变量赋给一样的值,就相当于把3个标签贴在同一个对象上。
用例子来说明:
a = 1 b = 2 c = 1 # 再次赋值 a = b
示意图:
通过输出 id(相当于内存地址)也可以说明这点:
在赋值之后,其实并不是 a 的值发生了变化,而是 a 的地址发生了变化。
理解了这点之后,你就会明白2件事:
- 当你给一个变量重新赋值之后,它就不再是之前的那个变量,所有的操作不会再影响到之前的变量上
- 当你给多个变量赋值相同的变量,它们其实都是同一个,只要改动其中之一,其他的也会跟着变化。(注意,是改动而非重新赋值,比如修改对象属性)
这个原理,在有关函数的参数传递、拷贝对象时都会涉及到。
因此,回到最初的问题,三个重新赋值其实本质是三个共用同一地址。
本文转载自微信公众号 Crossin的编程教室 ,为以后避免踩坑而记录。
有时候一天长的像一生,
有时候一生短的像一天。
世界上没有两个相同的一天,
但每一天都适合开始,
适合离别,适合爱。
——周一周二
评论
634600 688444I located your weblog web site on google and check a couple of of your early posts. Proceed to maintain up the superb operate. I just additional up your RSS feed to my MSN Data Reader. In search of forward to reading extra from you later on! 305212
I don’t even know how I ended up right here, but I thought this submit was once great. I do not know who you might be however definitely you are going to a famous blogger if you happen to aren’t already 😉 Cheers!
https://youtu.be/PFgLnyztAhg
852540 817274I view something genuinely special in this web site . 894274
I’m still learning from you, while I’m improving myself. I absolutely love reading all that is written on your blog.Keep the posts coming. I enjoyed it!
https://youtu.be/BanYFY6l55c
Right now it sounds like Drupal is the best blogging platform out there right now. (from what I’ve read) Is that what you’re using on your blog?
https://youtu.be/cWcTv825vdc
169299 188875I also recommend HubPages itself, and Squidoo, which is related. 62972
What i do not realize is actually how you are not really much more well-liked than you might be now. You are so intelligent. You realize thus considerably relating to this subject, made me personally consider it from so many varied angles. Its like women and men aren’t fascinated unless it is one thing to accomplish with Lady gaga! Your own stuffs nice. Always maintain it up!
https://youtu.be/gbOXHZMFe-U