总结
豆包 AI 助手文章总结

关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?

php中文网
发布: 2016-06-06 16:22:35
原创
1691人浏览过

为什么我觉得好不方便啊......
比如如下的代码:

<span class="n">x</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">]</span>
<span class="n">y</span><span class="o">=</span><span class="n">x</span>
<span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span><span class="mi">4</span>
<span class="k">print</span> <span class="n">x</span>
<span class="o">>></span> <span class="n">x</span> <span class="o">=</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span>
登录后复制

回复内容:

挺方便的
object.h
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?

而Python中一切皆来源于此,而这两个宏定义为:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?其实可发现PyObject_VAR_HEAD也只是PyObject_HEAD加上一个ob_size,于是Python中,每一个对象都拥有相同的对象头部,于是我们只需要用一个PyObject *就可以引用任意的一个对象,而不论该对象实际是一个什么对象,所以,当内存中存在某个Python对象时,该对象的开始的几个字节的含义一定会符合我们的预期,即PyObject_HEAD。而PyObject_HEAD宏定义中的_PyObject_HEAD_EXTRA其实只是指向_object的一个双向链表,
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?而ob_refcnt则是引用计数的计数器,而struct _typeobject *obtype则是类型,表示对象类型的类型对象:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?
通过PyObject_VAR_HEAD可以发现类型其实也是一个对象(一切皆对象),而类型对象的类型则是类型对象所关联的类型:PyType_Type:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?而即使如简单的int也是来填满这里的东西:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思? 关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?于是,即使是int也是对象
所以即使你使用
i = 47
j = 47
也是对47的一个引用,而
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?
通过id,可以看出其在内存引用位置相同,而为什么相同?因为为了减少频繁调用开销,使用了small int对象池的技术:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?于是只要超过257(包括257),则变了:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?所以, m,n虽然都是对258对象的引用,却是不同的内存地址了.

剩下的你就可以继续按照这条路线探寻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中有些对象是可以在原处进行改变的(即可变对象),这种对象包括了列表、字典、集合和一些自定义的对象。而对于整数和字符串等不可变对象是不会存在题主所说的问题。比如:
<span class="o">>>></span> <span class="n">a</span> <span class="o">=</span> <span class="mi">123</span>
<span class="o">>>></span> <span class="n">b</span> <span class="o">=</span> <span class="n">a</span>
<span class="o">>>></span> <span class="n">a</span> <span class="o">=</span> <span class="mi">321</span>
<span class="o">>>></span> <span class="k">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span>
<span class="mi">321</span> <span class="mi">123</span>
登录后复制
问题的关键是,你写下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()
python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
豆包 AI 助手文章总结
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号