鱼C论坛

 找回密码
 立即注册
查看: 3073|回复: 6

[技术交流] 【木有百科】一个很奇怪的赋值语句

[复制链接]
发表于 2014-8-31 20:38:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 mumudontcry 于 2014-9-16 12:14 编辑

在这里,木木先说下最近的近况:还在找工作中……
去面试了好几家游戏测试(大概就是玩游戏,找问题反馈问题的工作),然后我也不知道怎么回事,面试就是过不去,可能我实在不会表达吧
然后有别的公司找我,工资2000的,嗯……不想去,我觉得起码要3000吧,外加五险一金,然后工作时间不能超过8个小时,这两个是国家规定的标准
于是……这几天好累啊,但是我还是有在看python
有一次面试,hr给我的一个说法是,我还不知道自己的职业规划,就是不知道到底要做测试还是策划还是程序,其实我是都想做,只是想先测试开始,然后表达不清楚,又那什么了……
各位有没有什么建议或者意见呢?木木好想先找份工作做着

这里讲一个关于python的小知识,先看几段程序吧:
我们知道,python的定义变量的过程说得大众一点就是“取名字”,说得准确一点就是,变量名指向一个对象(字符串,数字,列表等),有点像指针
所以
a = ["木木"]
b = a
指的是a这个变量名指向包含“木木”字符串这个列表对象,b指向了a指向的对象,也就是b也指向了包含“木木”字符串这个列表
ps:赋值语句里,会把变量替换成变量名所代表的值

此时如果
a is b
那么结果是True,因为这两个是指向的一个对象

如果是
a = ["木木"]
b = ["木木"]
a is b
结果是False,此时a和b指向不同的对象,虽然值是相等的,比如a == b,结果是True


那么大家看看下面的句子,我已经把运行结果写上了,很奇怪的结果:
a = 1234567890987654321
b = 1234567890987654321
print(a is b)
print(a == b)
以及
a = 1
b = 1
print(a is b)
print(a == b)


============================
运行的结果是:
第一个:
False
True
第二个:
True
True

小伙伴们知道为什么么?




============================
答案:
就像3l测试的那样,木木给的答案是错的,因为结果还是True,其实也不能说错了,是python的问题,关于这个有一个解释:
python会把小整数和字符串进行缓存和复用,所以在定义b的时候,其实b指向了1这个缓存的对象,所以is之后是True,而1234567890987654321是个比较大的整数,所以没有被缓存,所以答案是False
不过正如3l测试的那样,真实的结果也是True,这……
昨天木木测试了一个比1234567890987654321还小的整数,结果就是False,今天再运行之后就是True(坑爹啊这是!),嗯……所以大家不用纠结一个对象是否被缓存和复用了,因为这里的“小”谁也不知道(或者等我知道了再告诉大家),会出现两次不同的结果我猜想是在我试用了大整数之后,python把这个“小”的范围扩大了,于是大整数也开始缓存了
这里python提供了一个函数可以查询某个对象被引用的次数,给“强迫症”小伙伴使用,在sys模块里有一个getrefcount函数,比如(请在idle gui里写,否则加上print):
import sys
sys.getrefcount(1)
答案是837(也可能是别的,要看你自己有没有引用1)
这种对象缓存复用机制跟代码没有关系(除非你用了这个函数),因为不能修改数字和字符串,所以对一个对象有多少引用都没关系,不过这个也反映了python为了执行速度采用优化的模块的众多方法之一

木木的建议,请使用分片([:])的方法复制一个列表,如果你实在不知道引用里的细节,那就不要去挑战python的权威
比如:
L1=[1,2,3]
L2=L1[:]
不要采用L2=L1,因为你这么做,会让L2也引用[1,2,3],修改L2的时候会同时修改L1!!!除非你就是要这么做
************************************************************
关注
木有百科
关注不一样的编程世界

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-8-31 21:16:33 From FishC Mobile | 显示全部楼层
本帖最后由 shuoye 于 2014-8-31 21:19 编辑

@小甲鱼 赋值列表时a=list b=a两个名字指到是同一个地址,字符串在数据不是很大时赋值的n变量也是指到同一个地址。我记得应该没错吧

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-9-1 10:00:14 | 显示全部楼层
360截图20140901100040597.jpg 版本问题?。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-1 14:50:34 | 显示全部楼层
shuoye 发表于 2014-8-31 21:16
@小甲鱼 赋值列表时a=list b=a两个名字指到是同一个地址,字符串在数据不是很大时赋值的n变量也是指到同一 ...

答案有点接近
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-1 15:00:54 | 显示全部楼层
wei_Y 发表于 2014-9-1 10:00
版本问题?。。

我今天运行了一下,结果跟你的答案一样……不能说我们谁对谁错,因为是python自己的问题,这个解释为:因为小的整数和字符串被缓存了然后又被复用了,所以is会告诉我们说是引用了一个对象
可是很坑爹的是,这个所谓的“小的整数和字符串”到底是小到什么程度?!!
昨天写帖子之前,我用了一个更小的整数,结果就是False,我不太了解这里面具体的机制,说不定is过一个比较大的整数之后,python就把“小”的范围扩大了……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-9-1 15:27:48 | 显示全部楼层
mumudontcry 发表于 2014-9-1 15:00
我今天运行了一下,结果跟你的答案一样……不能说我们谁对谁错,因为是python自己的问题,这个解释为:因 ...

嗯。明白了。Python真是个神奇的东西。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-9-1 21:58:49 | 显示全部楼层
讲的很好,受益
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-24 14:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表