设为首页 收藏本站
查看: 685|回复: 0

[经验分享] Python中的名称绑定

[复制链接]

尚未签到

发表于 2015-4-26 08:03:50 | 显示全部楼层 |阅读模式
作者:taowen
python中的name binding是非常好玩的,有意思。
大家还不知道什么叫name binding吧,就是假如你叫 “超人”, 然后超人就绑定到了你这个对象上,这个就是name binding了。
比如

  代码:[复制到剪贴板]  

  • a = 1

这个的意思就是把a 绑定到了对象 1 上面。而a的类型就是number了。
再看一个例子

  代码:[复制到剪贴板]  

  • a = [1,2,3]

a也绑定到了对象[1,2,3]上面。可以这么理解[1,2,3]是一个对象存在于内存之中,而a也是一个对象,不过它是一个对象标签一样的对象,任务就是用来引用[1,2,3]。你能够产生[1,2,3]这个对象,用[1,2,3]本身,或者list([1,2,3]),但是对象是一瞬即逝的。其实是一旦过去了你就没有凭据在茫茫内存之中找到[1,2,3]这个对象了。所以要用对象,你就要有一个名字,否则只能一次性使用了,也就是临时对象了。
比如就是这样:

  代码:[复制到剪贴板]  

  • len([1,2,3])

你执行完了len之后,得到3,但是之后再也没法找到那个[1,2,3]了,那个用于len([1,2,3])的[1,2,3]了。你可能还可以用[1,2,3]产生新的对象在内存中,他们毕竟只是一样而不是同一个。
但是你用name来绑定对象就可以做到长期使用了

  代码:[复制到剪贴板]  

  • mylist = [1,2,3]
  • len(mylist)
  • len(mylist+[4])

这里我们又可以看到mylist+[4]其实是另外一个临时对象了,其值应该是[1,2,3,4]。但是由于我们没有用某个名字绑定到mylist+[4]这个临时对象上,你将没法在使用一次之后再次使用。
尝试这样一个观点,name是一个对象,name绑定到的对象也是一个对象。
然后我们来看对于name的操作,对于name的引用大部分是作用到了name绑定的对象身上了:

  代码:[复制到剪贴板]  

  • mylist=[1,2,3]
  • len(mylist)

可以考虑,如果name是一个对象,其本身只是用来指向一个对象。那么其属性应该没有len可言,当然len这个函数操作的其实是mylist指向或者说是绑定到的对象。那么

  代码:[复制到剪贴板]  

  • len([1,2,3])

其实是len直接操作了列表[1,2,3],接收的参数是一个list,而不是一个绑定到了一个list的name。这种对于不同类型的参数表现的其实是不同的行为,一个是取出了绑定的对象求其长度,一个是直接求长度。应该看作函数的多态行为。类似的,对于操作符也有这样的行为:

  代码:[复制到剪贴板]  

  • mylist = [1,2,3]
  • anotherlist = [4,5]
  • print mylist+[4,5]
  • print mylist+anotherlist

这里+号对于左右两边都是name,以及一边是真实的list的两种不同情况表现的其实是不同的行为。不用多解释了吧,无非就是取出name绑定的对象,一个是直接操作list而已。那么再来看=号吧。

  代码:[复制到剪贴板]  

  • mylist = [1,2,3]
  • anotherlist = mylist
  • print mylist,anotherlist



  代码:[复制到剪贴板]  

  • mylist = [1,2,3]
  • anotherlist = list(mylist)
  • print mylist,anotherlist

这下你明白了我的意图吗?打印出来的值是一样的,但是行为是不同的。对于第一个程序。anotherlist 和mylist都是name,而不是真实的list对象。所以对于两个name的赋值行为,其实是把左边的name绑定到右边那么name绑定到的对象上。这样两个name就绑定到了同一个对象上。而加入左边曾经有一个绑定着的对象,那么那个对象如果没有其他name来绑定就无法找到了。
而对于第二个程序,anotherlist被赋给的是一个真实的list,是一个用list构造函数构造出来的临时对象(如果没有被绑定就是临时的了),只不过list构造函数被传入了一个参数,一个绑定了对象的name。这样其实anotherlist和mylist是绑定到了两个不同的对象,但是两个对象有相同的值。
检验的办法是

  代码:[复制到剪贴板]  

  • mylist = [1,2,3]
  • anotherlist = mylist
  • anotherlist[0] = 4
  • print mylist, anotherlist
  • anotherlist = list(mylist)
  • anotherlist[0] = 1
  • print mylist, anotherlist

分别打印的是
[4, 2, 3] [4, 2, 3]
[4, 2, 3] [1, 2, 3]
结果说明了一切。
最后提一点有关于对象回收的问题
前面多次说到了一个对象无法别找到,无法被索引到。其实当一个对象没有name绑定到它的时候,它内部有一个引用计数,这个时候应该是为零了。这个时候将被python的运行环境给回收。因为你找不到它,也就没法用它了,当然就可以安全的被销毁了。而加入是这样

  代码:[复制到剪贴板]  

  • mylist = [1,2,3]
  • anotherlist = mylist
  • del mylist

由于一开始的时候是mylist和anotherlist两个都绑定到了[1,2,3]身上,所以mylist的删除(其实是解除绑定,当一个name没有绑定到对象的时候就成为undefined的状态了)并不会导致[1,2,3]这个对象的实际销毁。

希望能够说明一些关于名称绑定上的问题。其实非常简单。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-60708-1-1.html 上篇帖子: Python函数默认参数的一个小陷阱 下篇帖子: Python天天美味(23)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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