免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2037 | 回复: 0
打印 上一主题 下一主题

Python中的增强赋值 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-04 10:36 |只看该作者 |倒序浏览
转:Yao  


Python中的增强赋值





从2.0开始,Python支持一组额外的赋值语句,称为增强赋值语句(Augmented assignment statements),比如“-=”,“+=”,“/=”等等。所谓“增强”是与通常写法比较而言,学过其它类似C,Java,C#等语言的同学都知道,“a += b”其实就等于"a = a + b",只是写法上有所简化。但在Python里,事情却没那么简单,里面猫腻还真不少……

为了方便查看内存的变化,需要用到“id”这个方法,它会返回python对象的整型标识符,其实在多数情况下这个“标识符”就是对象的内存地址,使用help(id),可以看到说明如下:
  1. 1 id(...)  

  2. 2     id(object) -> integer  

  3. 3   

  4. 4     Return the identity of an object.  This is guaranteed to be unique among  

  5. 5     simultaneously existing objects.  (Hint: it's the object's memory address.)
复制代码
后面的代码使用str(hex(id(...)))来打印出变量的地址。

先来看demo:
  1. 01 # -*- coding: utf-8 -*-  

  2. 02   

  3. 03 lst = [1,2,3,4]  

  4. 04   

  5. 05 print("Before: ", str(hex(id(lst))))  

  6. 06   

  7. 07 lst2 = lst  

  8. 08 print("List2  : ",str(hex(id(lst2))))  

  9. 09   

  10. 10 lst = lst + [5,6]    #普通赋值语句  

  11. 11 #lst += [5,6]        #增强赋值语句  

  12. 12   

  13. 13 print("After : ", str(hex(id(lst))))  

  14. 14   

  15. 15 print( lst is lst2 )
复制代码
在我机子上,输出为(注意:运行时具体数值可能会不同):
  1. 1 ('Before: ', '0xb786c5acL')  

  2. 2 ('List2 : ', '0xb786c5acL')  

  3. 3 ('After : ', '0xb788174cL')  

  4. 4 False
复制代码
可以看到,lst2 与lst地址相同,也就是说他们指向了同一个对象,就是所谓的"共享引用",这与预期相同。
第10行代码,lst与另外一个列表([5,6])做"+“运算时,首先会生成一个新的列表对象,然后lst指向这个新对象,这个过程中lst参与了两次运算(一次是参与新对象生成,第二次是指向新对象),这也在我们期望之中。

接下来,注释掉第10行代码,并取消第11行的注释,再次运行程序,结果如下:
  1. 1 ('Before: ', '0xb77355acL')  

  2. 2 ('List2 : ', '0xb77355acL')  

  3. 3 ('After : ', '0xb77355acL')  

  4. 4 True
复制代码
地址没变?!什么情况?原来在使用增强赋值语句时,Python会在可能的情况下执行原地(in-place)修改,比如,上面的代码,python会在lst原来的内存空间的后面“扩展”一些内存,用来存放[5,6],这样,lst其实只参与了一次运算,而且没有发生额外的内存复制,所以要比普通赋值语句执行更快!

在demo的第9行和第16行添加下面的代码,可以查看列表内每个元素的地址,来验证前面的结论。
  1. 1 for item in lst:  

  2. 2     print("Item%d: %x"%(item,id(item)))
复制代码
可以看到地址是连续的:
  1. 01 ('Before: ', '0xb77585acL')  

  2. 02 ('List2 : ', '0xb77585acL')  

  3. 03 Item1: 9d7bd68  

  4. 04 Item2: 9d7bd5c  

  5. 05 Item3: 9d7bd50  

  6. 06 Item4: 9d7bd44  

  7. 07 ('After : ', '0xb77585acL')  

  8. 08 True  

  9. 09 Item1: 9d7bd68  

  10. 10 Item2: 9d7bd5c  

  11. 11 Item3: 9d7bd50  

  12. 12 Item4: 9d7bd44  

  13. 13 Item5: 9d7bd38  

  14. 14 Item6: 9d7bd2c
复制代码
总的来说,写python代码时尽可能的多使用增强赋值语,因为它比普通赋值语句少了一次运算,而且在可能的情况下会执行原处(in-place)修改,执行起来也更快一些,也可以少打几个字

留个小问题:

上面加粗的“可能的情况”这几个字是什么意思,什么情况下会失败呢?可以把demo里的list改为integer,然后看看结果,然后思考list和integer这两种类型有什么不同?为什么会造成这种结果? Enjoy it!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP