比如如下的代码:
x=[1,2,3,4] y=x y[0]=4 print x >> x = [4 2 3 4]
回复内容:
挺方便的object.h
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
而Python中一切皆来源于此,而这两个宏定义为:
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
通过PyObject_VAR_HEAD可以发现类型其实也是一个对象(一切皆对象),而类型对象的类型则是类型对象所关联的类型:PyType_Type:
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
所以即使你使用
i = 47
j = 47
也是对47的一个引用,而
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
通过id,可以看出其在内存引用位置相同,而为什么相同?因为为了减少频繁调用开销,使用了small int对象池的技术:
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
![](http://m.sbmmt.com/m//zhstatic.zhihu.com/assets/zhihu/ztext/whitedot.jpg)
剩下的你就可以继续按照这条路线探寻Python的机制了,而你的问题也基本得到解答了,当你疑惑一些问题时,源码是最好的解释。 :-)
P.S. Python版本: 2.7.8 变量一般有三种风格:
引用式:变量是对象的名字,在运行时可以绑定到任意对象上,比如python。
值式:变量是存储位置的名字,在编译时绑定已经完成,运行时不可以改变,比如c。
混合式:某些类型是值式的,某些类型是引用式的,比如c#的struct和class。
c++比较特殊,基本上可以说是值式的,但是由于有别名存在,所以也有些引用式的特点。
引用式和值式的区别就是在赋值操作上,引用式的赋值是变量名的重新绑定,而值式的赋值是对象的拷贝。
他们两者是可以互相模拟的。引用式的想要有值式的赋值,只需要显式的拷贝或者copy-on-write就可以了。而值式的想要有引用式的赋值只需要使用指针就可以了。
你可能只是习惯了c/c++的值式的风格,还没适应引用式的风格。
看起来可能风格统一比较好。但是实际用起来我觉得c#的混合式是最好用的。 其实现在大部分的语言都是这样的:对象以引用的方式提供给编程者,对象赋值只是多个变量指向同一个对象。
大概只有C/C++的赋值是真的拷贝一份。
a = 258在Python看来就是:
创建一个PyIntObject对象,值为258;a是一个指向PyObject的指针,将a指向此PyIntObject对象之所以能这么干就和 @蓝色的答案解释的一样,所有的PyObject都有同样的头部。 在Python中有些对象是可以在原处进行改变的(即可变对象),这种对象包括了列表、字典、集合和一些自定义的对象。而对于整数和字符串等不可变对象是不会存在题主所说的问题。比如:
>>> a = 123
>>> b = a
>>> a = 321
>>> print a, b
321 123
问题的关键是,你写下y=x时,其实并没有新建一个y,而是一个类似c++中引用的机制,具体可以这样看:>>> x = [1,2,3,4]
>>> y = x
>>> id(x)
43246536L
>>> id(y)
43246536L
所以x和y其实是一个东西。
如果要复制一个list,需要使用
>>> y = list(x)
或者
>>> y = x[:] 你加上“指针”一起理解。 你想深拷贝就用y=x[:]。
其实也没啥不好的,py的对象分为可变和不可变两种,只要理解了这一点一切都很清晰。 id()
![VIP课程(WEB全栈开发)](http://m.sbmmt.com/img/upload/course/000/000/071/628e00599d7e4913.png)
相关文章推荐
• 【腾讯云】年中优惠,「专享618元」优惠券!• Python接口自动化测试必备基础之http协议详解• Python 3.11中的最佳新功能和功能修复• 实例详解Python面向对象的四大特征• Python数据分析之concat与merge函数(实例详解)• 一起聊聊Python的编码样式独孤九贱(3)_JavaScript视频教程
javascript是运行在浏览器上的脚本语言,连续多年,被评为全球最受欢迎的编程语言。是前端开发必备三大法器中,最具杀伤力。如果前端开发是降龙十八掌,好么javascript就是第18掌:亢龙有悔。没有它,你的前端生涯是不完整的。《php.cn独孤九贱(3)-JavaScript视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了javascript知识。
JavaScript教程125427次播放
独孤九贱(6)_jQuery视频教程
jQuery是一个快速、简洁的JavaScript框架。设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。 核心特性可以总结为:具有独特的链式语法和短小清晰的多功能接口;具有高效灵活的css选择器,并且可对CSS选择器进行扩展;拥有便捷的插件扩展机制和丰富的插件。兼容各种主流浏览器,如IE 6.0+、FF 1.5+、Safari 2.0+、Opera 9.0+等,是全球最流行的前端开发框架之一。PHP中文网根据最新版本,独家录制jQuery最新视频教程,回馈PHP中文网的新老用户。
jQuery教程103751次播放
jQuery与Ajax基础与实战
jQuery是最流行的JS函数库,封装了许多实用的功能,其中最引人入胜的就是Ajax。 jQuery中的Ajax操作,语法简单,操作方便,使Ajax从未如此轻松,前端人员从此不再为与服务器异步交互而发愁,本套课程,精选了最常用的几个方法,从基本的语法到每个参数,再到具体实例进行了全面的讲解。
AJAX教程4872次播放
Git教程(60分钟全程无废话版)
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持
JavaScript教程4194次播放